Joget DX 8 Stable Released
The stable release for Joget DX 8 is now available, with a focus on UX and Governance.
Table of Contents |
---|
English |
---|
In this tutorial, we will following the guideline of developing a plugin to develop our File Link Datalist Formatter. Please also refer to the very first tutorial How to develop a Bean Shell Hash Variable for more details steps. |
Thai |
---|
ในบทช่วยสอนนี้เราจะทำตามคำแนะนำ guideline of developing a plugin เพื่อพัฒนาตัวจัดรูปแบบไฟล์ดาต้าลิงค์ดาต้าลิสต์ของเรา โปรดอ้างอิงถึงบทช่วยสอนแรก How to develop a Bean Shell Hash Variable สำหรับขั้นตอนรายละเอียดเพิ่มเติม |
...
We need to always have our Joget Workflow Source Code ready and builded by following this guideline.
The following of this tutorial is prepared with a Macbook Pro and Joget Source Code version 5.0.0. Please refer to Guideline for developing Developing a pluginPlugin for other platform command.
Let said our folder directory as following.
Thai |
---|
เราจำเป็นต้องให้ซอร์สโค้ด Joget Workflow ของเราพร้อมและสร้างโดยปฏิบัติตาม this guideline บทช่วยสอนต่อไปนี้จัดทำขึ้นด้วย Macbook Pro และ Joget Source Code เวอร์ชั่น 5.0.0 โปรดอ้างอิง Guideline for developing Developing a pluginPlugin สำหรับคำสั่งแพลตฟอร์มอื่น ๆ ให้กล่าวว่าไดเรกทอรีโฟลเดอร์ของเราดังต่อไปนี้ |
Code Block |
---|
- Home - joget - plugins - jw-community -5.0.0 |
The "plugins" directory is the folder we will create and store all our plugins and the "jw-community" directory is where the Joget Workflow Source code stored.
Run the following command to create a maven project in "plugins" directory.
Thai |
---|
ไดเรกทอรี "ปลั๊กอิน" คือโฟลเดอร์ที่เราจะสร้างและจัดเก็บปลั๊กอินทั้งหมดของเราและไดเรกทอรี "jw-community" เป็นที่เก็บซอร์สโค้ด Joget Workflow เรียกใช้คำสั่งต่อไปนี้เพื่อสร้างโครงการ maven ในไดเรกทอรี "ปลั๊กอิน" |
Code Block | ||
---|---|---|
| ||
cd joget/plugins/ ~/joget/jw-community/5.0.0/wflow-plugin-archetype/create-plugin.sh org.joget.tutorial file_link_datalist_formatter 5.0.0 |
Then, the shell script will ask us to key in a version for your plugin and ask us for confirmation before generate the maven project.
Thai |
---|
จากนั้นเชลล์สคริปต์จะขอให้เราป้อนเวอร์ชันสำหรับปลั๊กอินของคุณและขอให้เรายืนยันก่อนที่จะสร้างโครงการ Maven |
Code Block | ||
---|---|---|
| ||
Define value for property 'version': 1.0-SNAPSHOT: : 5.0.0 [INFO] Using property: package = org.joget.tutorial Confirm properties configuration: groupId: org.joget.tutorial artifactId: file_link_datalist_formatter version: 5.0.0 package: org.joget.tutorial Y: : y |
We should get "BUILD SUCCESS" message shown in our terminal and a "file_link_datalist_formatter" folder created in "plugins" folder.
Open the maven project with your favour IDE. I will be using NetBeans.
Thai |
---|
เราควรได้รับข้อความ "BUILD SUCCESS" ที่ปรากฏในเครื่องของเราและโฟลเดอร์ "file_link_datalist_formatter" ที่สร้างในโฟลเดอร์ "plugins" เปิดโครงการ maven ด้วย IDE ที่คุณโปรดปราน ฉันจะใช้ NetBeans |
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
package org.joget.tutorial; import org.joget.apps.app.service.AppPluginUtil; import org.joget.apps.app.service.AppUtil; import org.joget.apps.datalist.model.DataList; import org.joget.apps.datalist.model.DataListColumn; import org.joget.apps.datalist.model.DataListColumnFormatDefault; public class FileLinkDatalistFormatter extends DataListColumnFormatDefault { private final static String MESSAGE_PATH = "messages/FileLinkDatalistFormatter"; public String getName() { return "File Link Datalist Formatter"; } public String getVersion() { return "5.0.0"; } public String getClassName() { return getClass().getName(); } public String getLabel() { //support i18n return AppPluginUtil.getMessage("org.joget.tutorial.FileLinkDatalistFormatter.pluginLabel", getClassName(), MESSAGE_PATH); } public String getDescription() { //support i18n return AppPluginUtil.getMessage("org.joget.tutorial.FileLinkDatalistFormatter.pluginDesc", getClassName(), MESSAGE_PATH); } public String getPropertyOptions() { return AppUtil.readPluginResource(getClassName(), "/properties/fileLinkDatalistFormatter.json", null, true, MESSAGE_PATH); } public String format(DataList dataList, DataListColumn column, Object row, Object value) { throw new UnsupportedOperationException("Not supported yet."); } } |
Then, we have to do a UI for admin user to provide inputs for our plugin. In getPropertyOptions method, we already specify our Plugin Properties Options definition file is locate at "/properties/fileLinkDatalistFormatter.json". Let us create a directory "resources/properties" under "file_link_datalist_formatter/src/main" directory. After create the directory, create a file named "fileLinkDatalistFormatter.json" in the "properties" folder.
In the properties definition options file, we will need to provide options as below. Please note that we can use "@@message.key@@" syntax to support i18n in our properties options.
Thai |
---|
จากนั้นเราต้องทำ UI สำหรับผู้ใช้ผู้ดูแลระบบเพื่อให้อินพุตสำหรับปลั๊กอินของเรา ในเมธอด getPropertyOptions เราได้ระบุไฟล์ข้อกำหนด Plugin Properties Options ไว้ที่ "/properties/fileLinkDatalistFormatter.json" แล้ว ให้เราสร้างไดเรกทอรี "resources / properties" ภายใต้ไดเรกทอรี "file_link_datalist_formatter / src / main" หลังจากสร้างไดเรกทอรีให้สร้างไฟล์ชื่อ "fileLinkDatalistFormatter.json" ในโฟลเดอร์ "properties" ในไฟล์ตัวเลือกคำจำกัดความของคุณสมบัติเราจะต้องระบุตัวเลือกดังต่อไปนี้ โปรดทราบว่าเราสามารถใช้ไวยากรณ์ "@@ message.key @@" เพื่อรองรับ i18n ในตัวเลือกคุณสมบัติของเรา |
Code Block | ||
---|---|---|
| ||
[{ title : '@@datalist.fileLinkFormatter.config@@', properties : [{ name : 'formDefId', label : '@@datalist.fileLinkFormatter.form@@', type : 'selectbox', options_ajax : '[CONTEXT_PATH]/web/json/console/app[APP_PATH]/forms/options', required : 'True' }, { name : 'attachment', label : '@@datalist.fileLinkFormatter.attachment@@', type : 'checkbox', options : [{ value : 'true', label : '' }] }] }] |
Thai |
---|
เมื่อเราทำตัวเลือกคุณสมบัติเพื่อรวบรวมอินพุตเราสามารถทำงานกับวิธีหลักของปลั๊กอินซึ่งเป็นวิธีการจัดรูปแบบ |
Code Block | ||
---|---|---|
| ||
public String format(DataList dataList, DataListColumn column, Object row, Object value) { String result = (String) value; if (result != null && !result.isEmpty()) { try { String formDefId = getPropertyString("formDefId"); AppDefinition appDef = AppUtil.getCurrentAppDefinition(); result = ""; String attachment = ""; if ("true".equals(getPropertyString("attachment"))) { attachment = "?attachment=true"; } //get the id of this record String primaryKeyValue = (String) LookupUtil.getBeanProperty(row, dataList.getBinder().getPrimaryKeyColumnName()); HttpServletRequest request = WorkflowUtil.getHttpServletRequest(); //suport for multi values for (String v : value.toString().split(";")) { if (!v.isEmpty()) { // determine actual path for the file uploads String fileName = v; String encodedFileName = fileName; try { encodedFileName = URLEncoder.encode(fileName, "UTF8").replaceAll("\\+", "%20"); } catch (UnsupportedEncodingException ex) { // ignore } String filePath = request.getContextPath() + "/web/client/app/" + appDef.getAppId() + "/" + appDef.getVersion().toString() + "/form/download/" + formDefId + "/" + primaryKeyValue + "/" + encodedFileName + "." + attachment; if (!result.isEmpty()) { result += ", "; } result += "<a href=\""+filePath+"\" target=\"_blank\">"+StringUtil.stripAllHtmlTag(fileName)+"</a>"; } } } catch (Exception e) { LogUtil.error(getClassName(), e, ""); } } return result; } |
Thai |
---|
จัดการไลบรารีการพึ่งพาของปลั๊กอินของคุณจัดการไลบรารีปลั๊กอินของคุณ |
Our plugin is using org.displaytag.util.LookupUtil and class, it required displaytag and jsp-api library. So, we have to add it to our POM file.
Thai |
---|
ปลั๊กอินของเราใช้ org.displaytag.util.LookupUtil และคลาสมันต้องการไลบรารี displaytag และ jsp-api ดังนั้นเราต้องเพิ่มลงในไฟล์ POM ของเรา |
Code Block | ||
---|---|---|
| ||
<!-- Change plugin specific dependencies here --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> </dependency> <dependency> <groupId>displaytag</groupId> <artifactId>displaytag</artifactId> <version>1.2</version> <exclusions> <exclusion> <artifactId>slf4j-api</artifactId> <groupId>org.slf4j</groupId> </exclusion> <exclusion> <artifactId>jcl104-over-slf4j</artifactId> <groupId>org.slf4j</groupId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency> <!-- End change plugin specific dependencies here --> |
Thai |
---|
เตรียมปลั๊กอินสากลให้พร้อม (i18n) |
We are using i18n message key in getLabel and getDescription method. We also used i18n message key in our properties options definition as well. So, we will need to create a message resource bundle properties file for our plugin.
Thai |
---|
เรากำลังใช้คีย์ข้อความ i18n ในวิธี getLabel และ getDescription นอกจากนี้เรายังใช้คีย์ข้อความ i18n ในการกำหนดตัวเลือกคุณสมบัติของเราเช่นกัน ดังนั้นเราจะต้องสร้างไฟล์คุณสมบัติมัดทรัพยากรสำหรับปลั๊กอินของเรา |
Create directory "resources/messages" under "file_link_datalist_formatter/src/main" directory. Then, create a "FileLinkDatalistFormatter.properties" file in the folder. In the properties file, let add all the message keys and its label as below.
Thai |
---|
สร้างไดเรกทอรี "ทรัพยากร / ข้อความ" ภายใต้ไดเรกทอรี "file_link_datalist_formatter / src / main" จากนั้นสร้างไฟล์ "FileLinkDatalistFormatter.properties" ในโฟลเดอร์ ในไฟล์คุณสมบัติให้เพิ่มคีย์ข้อความทั้งหมดและป้ายกำกับของมันดังต่อไปนี้ |
Code Block |
---|
org.joget.tutorial.FileLinkDatalistFormatter.pluginLabel=File Link Datalist Formatter org.joget.tutorial.FileLinkDatalistFormatter.pluginDesc=To format the column value as attachment download link. datalist.fileLinkFormatter.config=Configure File Link Formatter datalist.fileLinkFormatter.form=Form datalist.fileLinkFormatter.attachment=Download as Attachment? |
Thai |
---|
ลงทะเบียนปลั๊กอินของคุณไปที่ Felix Framework |
We will have to register our plugin class in Activator class (Auto generated in the same class package) to tell Felix Framework that this is a plugin.
Thai |
---|
เราจะต้องลงทะเบียนคลาสปลั๊กอินของเราในคลาส Activator (สร้างอัตโนมัติในแพ็คเกจคลาสเดียวกัน) เพื่อบอก Felix Framework ว่านี่คือปลั๊กอิน |
Code Block | ||
---|---|---|
| ||
public void start(BundleContext context) { registrationList = new ArrayList<ServiceRegistration>(); //Register plugin here registrationList.add(context.registerService(FileLinkDatalistFormatter.class.getName(), new FileLinkDatalistFormatter(), null)); } |
Thai |
---|
สร้างและทดสอบ |
Let build our plugin. Once the building process is done, we will found a "file_link_datalist_formatter-5.0.0.jar" file is created under "file_link_datalist_formatter/target" directory.
Then, let upload the plugin jar to Manage Plugins. After upload the jar file, double check the plugin is uploaded and activated correctly.
Thai |
---|
ให้สร้างปลั๊กอินของเรา เมื่อกระบวนการสร้างเสร็จสิ้นเราจะพบไฟล์ "file_link_datalist_formatter-5.0.0.jar" ถูกสร้างขึ้นภายใต้ไดเรกทอรี "file_link_datalist_formatter / target" จากนั้นให้อัปโหลด jar ปลั๊กอินไปที่ Manage Plugins หลังจากอัปโหลดไฟล์ jar ตรวจสอบอีกครั้งว่าปลั๊กอินถูกอัปโหลดและเปิดใช้งานอย่างถูกต้อง |
Let create a CRUD in userview to test our plugin. In list, let configure the File Upload field column as following.
Thai |
---|
ให้สร้าง CRUD ในมุมมองของเราเพื่อทดสอบปลั๊กอินของเรา ในรายการให้กำหนดค่าคอลัมน์ฟิลด์อัปโหลดไฟล์ดังนี้ |
In the CRUD list, we can see our file name is converted to a link.
Thai |
---|
ในรายการ CRUD เราสามารถเห็นชื่อไฟล์ของเราถูกแปลงเป็นลิงค์ |
Thai |
---|
ก้าวไปอีกขั้นแบ่งปันหรือขายมัน |
You can download the source code from file_link_datalist_formatter.zip.
To download the ready-to-use plugin jar, please find it in http://marketplace.joget.org/.
Thai |
---|
คุณสามารถดาวน์โหลดซอร์สโค้ดได้จาก file_link_datalist_formatter.zip หากต้องการดาวน์โหลด jar ปลั๊กอินที่พร้อมใช้งานโปรดค้นหาได้ที่ http://marketplace.joget.org/ |
...