PLEASE NOTE, a number of updates have been made to this guide which appear in italics for easy identification.
Wappler opens up its extensibility powers!
Now you can define your own custom modules and formatters for Server Connect. You can write your own custom code but also provide a UI definition of your extensions so they integrate directly visually in Wappler!
Writing Extensions for Server Connect
Folder Structure
All extensions files are placed in your project folder under the following folders:
-
for modules:
extensions/server_connect/modules
-
for formatters
extensions/server_connect/formatters
Writing Server Code
The server code for your module or formatters depend on your server model. So check:
- Writing Custom Modules and Formatters (PHP)
- Writing Custom Modules and Formatters (NodeJS)
- Writing Custom Modules and Formatters (ASP)
Extensions UI
To define an UI for your module actions or formatters, you need to place a special Hjson file that describes your UI. Hjson is just a more readable json format that makes it easier to write.
The Module UI
You can place your Hjson file in extensions/server_connect/modules/mymodule.hjson
An example is:
{
type: 'world_hello',
module : 'world',
action : 'hello',
groupTitle : 'Custom Actions',
groupIcon : 'fas fa-lg fa-database comp-data',
title : 'Hello World',
icon : 'fas fa-lg fa-table comp-data',
dataScheme: [
{name: 'name', type: 'text'},
{name: 'age', type: 'number'}
],
dataPickObject: true,
globalVars: {
'$_GET' : [
{name: 'sort', type: 'text'},
{name: 'dir', type: 'text'}
]
},
properties : [
{
group: 'Hello Properties',
variables: [
{ name: 'actionName', optionName: 'name', title: 'Name',
type: 'text', required: true, defaultValue: ''},
{ name: 'actionData', optionName: 'data', title: 'Data',
type: 'text', defaultValue: ''}
]
}
]
}
As you can see the structure is pretty readable. You define a type name for your module, usually a combination of module name and action, give it some titles and icons, define the output scheme if needed and specify input variables.
Note: You can have multiple actions within the same module. So you can also have multiple UI definitions for those actions in the same Hjson file. Just put an array element around them - enclose them in brackets and make sure there is a comma between.
Module UI Options
Key | Type | Description |
---|---|---|
type | text, required | an unique name for your module |
module | text, required | an unique module name |
action | text, required | an unique action name within this module |
groupTitle | text, required | an group title to show all modules with the same group name together |
groupIcon | text, required | an font awesome icon for the group, use also color modifiers |
title | text, required | an title that describes your action |
icon | text, required | an font awesome icon for action, use also color modifiers |
dataScheme | array, optional | an array of objects with name and type that define the output data for your action |
dataPickObject | boolean, optional | is the main action name pickable as data |
globalVars | object, optional | an object that defines input data to be auto defined when the action is inserted |
properties | array, optional | an array of groups with properties defining the input of the action. You can have multiple groups |
Module UI Variables
For each group of UI input options you can have multiple variables with the following structure:
{ name: 'actionName', optionName: 'name', title: 'Name',
type: 'text', required: true, defaultValue: ''},
where:
Key | Type | Description |
---|---|---|
name | text, required | an unique name for your input variable on the UI |
optionName | text, required | the name that gets used as option |
title | text, required | the prompt for the variable on the UI |
type | text, required | the input variable display type, see display types |
required | boolean, optional | is the input required |
defaultValue | text/boolean, optional | the default value for this input |
serverDataBindings | boolean, optional | display a data bindings picker next to the input for easy data pickup. This also makes your control a visual expression tag editor |
help | text, optional | the help text describing this input |
A name variable as shown above is mandatory. Other variables are optional
The name definition has one further useful property specific to it allowing a default name to be displayed for the module like this
Adding baseName: "mymodule1" will lead to this
"Output" should always be set to a default of false of the function may not function correctly
Platforms
Your extension may be available for one or more platforms. The available platforms are specified in the HJSON head. This is then used when adding to npm repository as a directlive
If omitted then it is assumed that the extension is available to all platforms
Adding serverModel: ['node', 'PHP'] will specify availability on both node and PHP platforms or availability can be limited by serverModel: ['node'], or serverModel: ['PHP'],
The Formatter UI
You can place your HJson file in extensions/server_connect/formatters/myformatter.hjson
An example is:
{
type: 'method_boeh',
groupTitle : 'Custom Formatters',
groupIcon : 'fa fa-lg fa-key',
addTitle: 'Add Boeh',
title : 'Add Boeh',
icon : 'fa fa-lg fa-hashtag',
state : 'opened',
help : 'Say boeh en more',
properties : [
{
group: 'Boeh Properties',
variables: [
{
name: '1', optionName: '1', title: 'Param 1', type: 'text',
serverDataBindings: true, defaultValue: '',
help: 'Some great param.'
}
]
}
]
}
As you can see the structure is similar to the module UI, except you don't have module and action. You define a type name for your module, must start with "method_" , give it some titles and icons, and specify input variables.
Note: You can have multiple formatters within the same code file. So you can also have multiple UI definitions for those formatters in the same Hjson file. Just put an array element around them - enclose them in brackets and make sure there is a comma between.
Formatter UI Options
Key | Type | Description |
---|---|---|
type | text, required | an unique name for your formatter, must start with "method_" |
groupTitle | text, required | an group title to show all formatter with the same group name together |
groupIcon | text, required | an font awesome icon for the group, use also color modifiers |
title | text, required | an title that describes your formatter |
icon | text, required | an font awesome icon for the formatter, use also color modifiers |
properties | array, optional | an array of groups with properties defining the input of the formatter. You can have multiple groups |
Formatter UI Variables
For each group of UI input options you can have multiple variables with the following structure:
{ name: '1', optionName: '1', title: 'Param 1',
type: 'text', required: true, defaultValue: ''},
where:
Key | Type | Description |
---|---|---|
name | text, required | is the order number of the parameter starting with 1 |
optionName | text, required | same as name |
title | text, required | the prompt for the variable on the UI |
type | text, required | the input variable display type, see display types |
required | boolean, optional | is the input required |
defaultValue | text/boolean, optional | the default value for this input |
serverDataBindings | boolean, optional | display a data bindings picker next to the input for easy data pickup. This also makes your control a visual expression tag editor |
help | text, optional | the help text describing this input |
Input Reference
For both Module UI and Formatters UI the same variables options are valid.
Display Types
Type | Description |
---|---|
text | display text input |
textarea | display textarea |
boolean | display checkbox |
number | display number only input |
numberorstring | display number or string input |
file | choose a file |
folder | choose a folder |
static | not an input control but just a static text - use .help field to specify contents |
droplist | an advanced dropdown select control, see advanced types below* |
enum | an advanced multiselect control, see advanced types below* |
*NOTE the input type "number" can only accept static numeric values and the picker will be disabled. The use of "number" type is not recommended.
If a dynamic value is needed, use "text" or "numberorstring". In most cases text will suffice.
Advanced Display Types
You can use also advanced display controls like dropdowns and multiple selectors
example:
{ name: 'oauth_service', optionName: 'service', title: 'Service',
type: 'droplist',
values: [
{title: 'Google', value: 'google' },
{title: 'Facebook', value: 'facebook' },
{title: 'Instagram', value: 'instagram' },
{title: 'Default', value: ''}
], defaultValue: '',
help: 'Choose your OAuth2 Provider.'
}
*NOTE, the default value as below only acts on the dropdown action selecting the action displayed. *
should you wish to return a default value if it is selected then you must add
initValue: "your_initial_value",
after the default value
You can also add a grid input like this.
{
name: "headings",
optionName: "headings",
key: "var",
keyValue: "value",
title: "Your Grid title",
type: "grid",
defaultValue: {},
serverDataBindings: true,
columns: [
{
field: "var",
caption: "your key caption here",
size: "30%",
editable: {
type: "static"
}
},
{
field: "value",
caption: "Your value caption here",
size: "70%",
editable: {
type: "datapicker"
}
}
]
}
Conditional Fields
Sometimes you need to show and hide some fields depending on chosen values of others.
So with the droplist field for example you can easily specify for each choice which fields to show or hide:
{ name: 'oauth_service', optionName: 'service', title: 'Service',
type: 'droplist',
values: [
{title: 'Google', value: 'google', show:['oauth_key', 'oauth_url'], hide:[] },
{title: 'Facebook', value: 'facebook', show:[], hide:['oauth_key', 'oauth_url'] },
{title: 'Instagram', value: 'instagram', show:[], hide:['oauth_key', 'oauth_url'] },
{title: 'Default', value: '', show:[], hide:['oauth_key', 'oauth_url']}
], defaultValue: '',
help: 'Choose your OAuth2 Provider.'
},
{ name: 'oauth_key', optionName: 'key', title: 'Api Key',
type: 'text', defaultValue: '', initDisplay: 'none'},
{ name: 'oauth_url', optionName: 'url', title: 'URL',
type: 'text', defaultValue: '', initDisplay: 'none'},
Here only when Google is chosen, we display the additional two field otherwise they are just hidden - also initially with initDisplay option.
Color modifiers
Key | Description |
---|---|
comp-flows | color for flows |
comp-errors | color for errors |
comp-data | color for data elements |
comp-loops | color for loop actions |
comp-general | general color |
comp-settings | color for settings |
comp-exec | color for executions |
comp-dialogs | color for dialogs |
comp-files | color for files and operations |
comp-images | color for images |
comp-security | color for security |
Installing Additional Modules
Your custom extensions for NodeJS or PHP might need some special Modules/Packages. Now you can specify those in the Hjson and they will be installed automatically. Just add the following in your Hjson definition. You can pass multiple modules and required versions.
For NodeJS:
usedModules : {
node: {
"sharp": "^0.29.3"
}
}
For PHP - when using PHP Composer, requires Wappler 5.6+
usedModules : {
PHP: {
"chillerlan/php-qrcode": "^4.3"
}
}
Packaging your custom modules and formatters
For packaging your custom Server Connect modules and formatters in a Wappler Extensions see: