Wappler Extensibility - Writing Custom Modules and Formatters for Server Connect

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:

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

image

"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:

14 Likes

Going to have so much fun with this! :smiley:

Great update guys!

3 Likes

Same here! And why is this a minor version? Surely this justifies being v3.5.0? :slight_smile:

2 Likes

They are just flexing :joy:

4 Likes

There is no need to use anything other than wappler anymore :)) it was amazing …
thanks @patrick :+1: :+1: :+1: :+1: :+1: @George :+1: :+1: :+1: :+1: :+1: :+1: @Teodor :+1: :+1: :+1: :+1: :+1: :+1:

1 Like

how can we share new formatters , modules etc … in forum … @George

6 Likes

I was just thinking there should be some kind of marketplace for people to put new modules.

2 Likes

I would strongly advise against that :slight_smile: Not a central repository, but the marketplace thingy.

2 Likes

yes free

1 Like

For what reason?

I'm thinking of a place where people can put modules for others to use. Not where things are sold. Sorry, marketplace is the standard term for such a thing but does imply costs... I would be against that. But if I have a niche feature which I think could help others, somewhere I can post it for them to use would be good. Let's not all invent the same wheel.

3 Likes

I fully agree

I think a central repository makes more sense. We need a wpm -> Wappler package manager :slight_smile:

6 Likes

I was fascinated by learning Dart + Flutter and lost sight of Wappler a bit.

I went to see the updates. And here it is… :honey_pot:

Guys how do you do it?

Wappler:
giphy

2 Likes

My opinion ,
In the wappler UI, the formatters created by the users can be a field for the module, so the user can add any module or formatter they want to the project.

I think using them in place other than Wappler UI will direct users to a different area. Also, these modules should be free. wappler is not BUBBLE :wink:

3 Likes

Well it’s a preview :slight_smile: and much more is coming - we just touched the server side, but there is also client side, app connect components, css design frameworks :slight_smile:

8 Likes

I knew App Connect was coming…it was the obvious next step…but css design frameworks???

I need a harder than beer :grinning:

Well you can start with github repos, later we will also introduce a special package - like a zip file with special extension that you can just drop in Wappler to install.

11 Likes

Even though this stuff is way above my skillset and knowledge this seem like an amazing new path for Wappler. Exciting.

4 Likes