Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

6. เตรียม environment ของคุณเพื่อการพัฒนา

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 บทช่วยสอนต่อไปนี้จัดทำขึ้นด้วย Macbook Pro และ Joget Source Code version 5.0.0. Please refer to แนวทางสำหรับการพัฒนาปลั๊กอิน for other platform command.โปรดอ้างอิงถึง แนวทางสำหรับการพัฒนาปลั๊กอิน เพื่อคำสั่งแพลตฟอร์มอื่นๆ

ให้กล่าวว่าไดเรกทอรีโฟลเดอร์ของเราดังต่อไปนี้Let said our folder directory as following. 

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.คือโฟลเดอร์ที่เราจะสร้างและจัดเก็บปลั๊กอินทั้งหมดของเราและไดเรกทอรี "jw-community" เป็นที่เก็บซอร์สโค้ด Joget Workflow

เรียกใช้คำสั่งต่อไปนี้เพื่อสร้างโครงการ maven ในไดเรกทอรี "ปลั๊กอิน"Run the following command to create a maven project in "plugins" directory.

Code Block
languagebash
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.

จากนั้น the shell script จะขอให้เราป้อนปลั๊กอินสำหรับรุ่นของคุณและขอให้เรายืนยันก่อนสร้างโครงการ maven

Code Block
languagebash
Define
Code Block
languagebash
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.  เปิดโครงการ maven ด้วย IDE ที่คุณโปรดปราน เราแนะนำให้ใช้ NetBeans.  

7.

...

เริ่มโค้ด!

a. Extending the abstract class of a plugin type

Create a สร้างคลาส "FileLinkDatalistFormatter" class under ภายใต้ "org.joget.tutorial" package. Then, extend the class with จากนั้นขยายคลาสด้วย org.joget.apps.datalist.model.DataListColumnFormatDefault abstract class. โปรดอ้างอิงถึง Please refer to ปลั๊กอินตัวจัดรูปแบบคอลัมน์ข้อมูล (Datalist Column Formatter Plugin).

b. Implement all the abstract methods

As usual, we have to implement all the เช่นเคยเราจะต้องใช้ abstract methods ทั้งหมด. We will using เราจะใช้ AppPluginUtil.getMessage method to support i18n and using constant variable เพื่อสนับสนุน i18n และใช้ตัวแปรคงที่ MESSAGE_PATH for สำหรับ message resource bundle directory.

 

Code Block
languagejava
titleImplementation of all basic abstract methods
collapsetrue
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 ตัวเลือกคุณสมบัติปลั๊กอิน definition file is locate at จากนั้นเราต้องทำ UI สำหรับผู้ใช้ผู้ดูแลระบบเพื่อให้อินพุตสำหรับปลั๊กอินของเรา ใน getPropertyOptions method, เราได้ระบุไฟล์ ตัวเลือกคุณสมบัติปลั๊กอิน ของเราไว้ที่ "/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.เพื่อสนับสนุน i18n ในตัวเลือกคุณสมบัติของเรา

Code Block
languagejs
[{
    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 : ''
        }]
    }]
}]
 
Once we done the properties option to collect input, we can work on the main method of the plugin which is format method.เมื่อเราทำตัวเลือกคุณสมบัติเพื่อรวบรวมอินพุตแล้วเราสามารถทำงานกับวิธีหลักของปลั๊กอินซึ่งเป็นวิธีการจัดรูปแบบ

 

Code Block
languagejava
    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;
    }

 

c.

Manage the

จัดการ dependency libraries

of your plugin

ของปลั๊กอินของคุณ

ปลั๊กอินของเราใช้คลาส Our plugin is using org.displaytag.util.LookupUtil and  class, it required displaytag and และมันจำเป็นต้องใช้ displaytag และ jsp-api library. So, we have to add it to our POM file.ดังนั้นเราต้องเพิ่มในไฟล์ POM ของเรา

Code Block
languagexml
<!-- 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 -->

d.

Make your plugin

ทำปลั๊กอิน internationalization (i18n)

ready

ของคุณให้พร้อม

We are using เรากำลังใช้ i18n message key in ใน getLabel and และ getDescription method. We also used i18n เรายังใช้ 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.สำหรับปลั๊กอินของเรา

สร้าง 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.ในโฟลเดอร์ ในไฟล์ตัวเลือกเราต้องเพิ่ม message keys และ label ดังต่อไปนี้

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?

e.

Register your plugin to

ลงทะเบียนปลั๊กอินของคุณืี่ Felix Framework

We will have to register our plugin class in Activator เราจะต้องลงทะเบียนคลาสปลั๊กอินของเราใน Activator class (Auto generated in the same class package) to tell เพื่อบอก Felix Framework that this is a plugin.ว่านี่คือปลั๊กอิน

Code Block
languagejava
    public void start(BundleContext context) {
        registrationList = new ArrayList<ServiceRegistration>();
        //Register plugin here
        registrationList.add(context.registerService(FileLinkDatalistFormatter.class.getName(), new FileLinkDatalistFormatter(), null));
    } 

f. สร้างและทดสอบ

ให้สร้างปลั๊กอินของเรา เมื่อกระบวนการสร้างเสร็จสิ้นเราจะพบไฟล์ "file_link_datalist_formatter-5.0.0.jar" ถูกสร้างขึ้นภายใต้ไดเรกทอรี "file_link_datalist_formatter / target"

จากนั้นให้อัปโหลดปลั๊กอินไปที่ Manage Plugins. หลังจากอะพโหลดไฟล์ jar, ตรวจสอบอีกครั้งว่าปลั๊กอินนั้นถูกอัพโหลดและเปิดใช้งานอย่างถูกต้อง

ให้สร้าง CRUD ในมุมมองของเราเพื่อทดสอบปลั๊กอินของเรา ในรายการให้กำหนดค่าคอลัมน์ฟิลด์อัปโหลดไฟล์ดังนี้

ในรายการ CRUD เราจะเห็นว่าไฟล์ของเราถูกแปลงเป็นลิงค์

8. ขั้นต่อไป แชร์หรือขาย

คุณสามารถดาวน์โหลด source code จาก file_link_datalist_formatter.zip.

หากต้องการดาวน์โหลด jar ปลั๊กอินที่พร้อมใช้งานโปรดค้นหา http://marketplace.joget.org/.

...