...
a. Extending the abstract class of a plugin type
Refer to the document of the plugin type listed in Plugin Types, find the abstract class and interface that need to extends and implements by your plugin.
Example: To develop a Userview Menu plugin, the plugin class need to extends the org.joget.apps.userview.model.UserviewMenu abstract class.
b. Implement all the abstract methods
A plugin will has to implements the abstract method of Plugin Base Abstract Class and Interface and also the abstract method of the individual abstract class and interface for the plugin type.
Example: To develop a Userview Menu plugin, the following methods have to implemented by the plugin. Please refer to the plugin documents for the details of each methods.
- getCategory
- getClassName
- getDecoratedMenu
- getDescription
- getIcon
- getLabel
- getName
- getPropertyOptions
- getRenderPage
- getVersion
- isHomePageSupported
c. Manage the dependency
...
libraries of your plugin
The generated plugin folder by "wflow-plugin-archetype" module is a maven project. So, we will using the Dependency Mechanism provided by Maven.
d. Make your plugin internationalization (i18n) ready
To make the plugin i18n ready, we need to create a message resource bundle property file for the plugin.
- Create a property file with the plugin class name in "[Plugin project directory]/src/main/resources/message" directory.
Example: For a plugin named "GanttChartMenu", we need to create a "GanttChartMenu.properties" file under "[Plugin project directory]/src/main/resources/message" directory.
Sample content for GanttChartMenu.properties file
Code Block language java org.joget.sample.GanttChartMenu.pluginLabel=Gantt Chart org.joget.sample.GanttChartMenu.pluginDesc=To display form data in Gantt Chart layout userview.ganttChart.label.title=Title userview.ganttChart.label.week=Week
- Used getMessage(String key, String pluginName, String translationPath) of PluginManager or AppPluginUtil to retrieve i18n label.
Example: Use the getMessage method in getLabel and getDescription methods to return i18n label and description.
Code Block language java public String getLabel() { return AppPluginUtil.getMessage("org.joget.sample.GanttChartMenu.pluginLabel", getClassName(), "message/GanttChartMenu"); } public String getDescription() { return AppPluginUtil.getMessage("org.joget.sample.GanttChartMenu.pluginDesc", getClassName(), "message/GanttChartMenu"); }
- Pass a translation file path to readPluginResource(String pluginName, String resourceUrl, Object[] arguments, boolean removeNewLines, String translationFileName) method of AppUtil to provide the plugin properties option with i18n label. We can use "@@message.key@@" in the JSON of Plugin Properties Options.
Example: For property options of a GanttChartMenu plugin, the following show the sample code implementation of getPropertyOptions method and the GanttChartMenu.json file
Code Block language java public String getPropertyOptions() { return AppUtil.readPluginResource(getClassName(), "/properties/GanttChartMenu.json", null, true, "message/GanttChartMenu"); }
Code Block language js [{ title : '@@userview.ganttChart.edit@@', properties : [{ name : 'id', label : 'Id', type : 'hidden' }, { name : 'customId', label : '@@userview.ganttChart.customId@@', type : 'textfield', regex_validation : '^[a-zA-Z0-9_]+$', validation_message : '@@userview.ganttChart.invalidId@@' }, { name : 'label', label : '@@userview.ganttChart.label@@', type : 'textfield', required : 'True', value : '@@userview.ganttChart.label.value@@' }] }]
- Pass a translation file path to getPluginFreeMarkerTemplate(Map data, final String pluginName, final String templatePath, String translationPath) method of PluginManager whenever retrieving a HTML template. Once we passed a translation file path, we can use "@@message.key@@" in the freemarker template to retrieve i18n label.
Example: For getRenderPage method of a GanttChartMenu plugin, the following show the sample code implementation of getRenderPage method and the "GanttChartMenu.ftl" FreeMarker template.
Code Block language java public String getRenderPage() { Map model = new HashMap(); model.put("request", getRequestParameters()); model.put("element", this); PluginManager pluginManager = (PluginManager)AppUtil.getApplicationContext().getBean("pluginManager"); String content = pluginManager.getPluginFreeMarkerTemplate(model, getClasstName(), "/templates/GanttChartMenu.ftl", "message/GanttChartMenu"); return content; }
Code Block language xml <div> <h1>@@userview.ganttChart.label.title@@ : ${element.properties.title!}</h1> </div>
- Postfix the plugin class name with an underscore and language code to create a message resource bundle property file for other language.
Example: GanttChartMenu_zh_CN.properties
e. Register your plugin to Felix Framework
You will found a class named "Activator.java" is auto generated in a package of your plugin maven project. The class is used to register your plugin class to Felix Framework. You do not need to do this if your plugin is not an OSGI Plugin.
In the start method of the activator class, add your plugin class to the "registrationList" variable.
Code Block | ||
---|---|---|
| ||
public void start(BundleContext context) {
registrationList = new ArrayList<ServiceRegistration>();
//Register plugin here
registrationList.add(context.registerService(MyPlugin.class.getName(), new MyPlugin(), null));
} |
f. Build it and testing
Once you done all the steps above, you can build your project with your IDE using Maven. You can also run "mvn clean install" command in your project directory to build it. After building your project, a jar file is created under "target" folder in your plugin project folder. Upload the plugin jar to Manage Plugins to test your plugin.
Example: In NetBeans, click the "Clean and Build" after right click on the project name.
8. Take a step further, share it or sell it
...