Building Form Engine Control Plugins

In Build a Form Engine Control, we learned how to build form engine controls placed in the Studio war file. Crafter Studio also allows plugins for form engine controls through the getPluginFile API found here https://app.swaggerhub.com/apis/craftercms/studio/3.1.8.2#/plugin/getPluginFile

The anatomy of a Control Plugin

Form Engine Control consist of (at a minimum)

  • A single javascript file which implements the control interface.

    • Unlike in the previous section Build a Form Engine Control, the JS file name and the control name in the configuration does not need to be the same. The JS file name can be any meaningful name, different from the control name in the configuration.

  • Configuration in a Crafter Studio project to make that control available for use

Interface

See Control Interface for more information on form engine control interface.

Plugin Directory Structure

When using plugins, the JS files location for the plugins uses a convention where the files needs to go in the following location:

  • Controls : CRAFTER_HOME/data/repos/sites/SITE_NAME/sandbox/config/studio/plugins/control/CONTROL_NAME/JS_FILE.js

where:

  • CRAFTER_HOME : Studio location

  • SITE_NAME : Name of site where the plugin is to be added

  • CONTROL_NAME : Name of form engine control plugin

  • JS_FILE.js : JavaScript file containing the control/data source interface implementation

Note

When using an out-of-the-box blueprint to create your site, the plugins/control folder does not exist under CRAFTER_HOME/data/repos/sites/SITE_NAME/sandbox/config/studio/ and will need to be created by the user creating the plugins.

Form Engine Control Example

Let’s take a look at an example of a control plugin. We will be adding a control named text-input.

Form Engine Control Code

The first thing we have to do is to create the folder structure where we will be placing the JS file for our control. We’ll follow the convention listed above in Plugin Directory Structure

Under CRAFTER_HOME/data/repos/sites/SITE_NAME/sandbox/config/studio, create the folder plugins. Under the plugins folder, create the folder control. Under the control folder, create the folder text-input, which is the name of the control we’re building. We will be placing the JS file implementing the control interface under the text-input folder. In the example below, the JS file is main.js

Form Engine Control Plugin Directory Structure

In the JS file, please note that the CStudioAuthoring.Module is required and that the prefix for CStudioAuthoring.Module.moduleLoaded must be the name of the control. For our example, the prefix is text-input as shown in the example.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
CStudioForms.Controls.textInput = CStudioForms.Controls.textInput ||
function(id, form, owner, properties, constraints, readonly)  {
    this.owner = owner;
    this.owner.registerField(this);
    this.errors = [];
    this.properties = properties;
    this.constraints = constraints;
    this.inputEl = null;
    this.patternErrEl = null;
    this.countEl = null;
    this.required = false;
    this.value = "_not-set";
    this.form = form;
    this.id = id;
    this.readonly = readonly;

    return this;
}

YAHOO.extend(CStudioForms.Controls.textInput, CStudioForms.CStudioFormField, {

    getLabel: function() {
        return CMgs.format(langBundle, "Text Input");
    },
    .
    .
    .

    getName: function() {
            return "text-input";
    },

    getSupportedProperties: function() {
        return [
                { label: CMgs.format(langBundle, "displaySize"), name: "size", type: "int", defaultValue: "50" },
                { label: CMgs.format(langBundle, "maxLength"), name: "maxlength", type: "int",  defaultValue: "50" },
                { label: CMgs.format(langBundle, "readonly"), name: "readonly", type: "boolean" },
                { label: "Tokenize for Indexing", name: "tokenize", type: "boolean",  defaultValue: "false" }
        ];
    },

    getSupportedConstraints: function() {
        return [
                { label: CMgs.format(langBundle, "required"), name: "required", type: "boolean" },
                { label: CMgs.format(langBundle, "matchPattern"), name: "pattern", type: "string" },
        ];
    }

});

CStudioAuthoring.Module.moduleLoaded("text-input", CStudioForms.Controls.textInput);

After placing your JS file, we need to commit the new file to the repo ({CRAFTER_HOME}/data/repos/sites/SITENAME/sandbox/) by using git so the control will appear in the site content types.

Crafter uses a vanilla version of Git, so regular Git commands work as intended. To commit your changes so Crafter can see it, head to {CRAFTER_HOME}/data/repos/sites/SITENAME/sandbox/ and git add your new files like this

git add <filename>

for each filename. Or, if multiple controls were added, to add all at once use:

git add --all

And once you are done, commit them with the following command:

git commit -m "<the commit’s description>"

You can also use any Git client. Now, it will be available when you edit or create a new content type in your site. Remember that whenever you edit directly in the filesystem, you need to commit your changes to ensure they are properly reflected.

Configuring the Control to show up in Crafter Studio

Add the plugin control’s name to the list of controls in the content type editor configuration

Location (In Repository) SITENAME/config/studio/administration/site-config-tools.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<controls>
    <control>
        <name>auto-filename</name>
        .
        .
    </control>
    .
    .
    <control>
        <plugin>
            <type>control</type>
            <name>text-input</name>
            <filename>main.js</filename>
        </plugin>
        <icon>
            <class>fa-pencil-square-o</class>
        </icon>
    </control>
</controls>

Here’s our plugin control added to the list of controls in the site content types

Form Engine Control Plugin Added to Content Type