ในบทเรียนนี้เราจะทำตาม guideline of developing a plugin เพื่อพัฒนาปลั๊กอิน File Link Datalist Formatter ของเรา โปรดอ้างอิงถึงบทเรียนแรก วิธีการพัฒนา Bean Shell Hash Variable สำหรับรายละเอียดเพิ่มเติม

1. ปัญหาคืออะไร?

เรามีไฟล์ที่อัพโหลดโดยใช้ฟิลด์อัพโหลดไฟล์ในฟอร์ม เราต้องการแสดงชื่อไฟล์เป็นลิงค์สำหรับดาวน์โหลดไฟล์ใน datalist ของเรา

2. ความคิดของคุณในการแก้ปัญหาคืออะไร?

เราสามารถพัฒนา ปลั๊กอินตัวจัดรูปแบบคอลัมน์ข้อมูล (Datalist Column Formatter Plugin) เพื่อแปลงค่าเป็นลิงค์

3. อินพุตที่จำเป็นสำหรับปลั๊กอินของคุณคืออะไร?

รูปแบบลิงค์ดาวน์โหลดไฟล์ของ Joget Workflow คือ

/jw/web/client/app/{appId}/{appVersion}/form/download/{formId}/{recordId}/{fileName}.?attachment=true

ตัวอย่าง:

http://localhost:8080/jw/web/client/app/test/1/form/download/testFile/f6946830-c0a80070-48cad9b7-8b971682/CHANGES.txt.?attachment=true

จากรูปแบบลิงก์เราต้องได้รับข้อมูลต่อไปนี้จากผู้ใช้งาน admin

  1. Form Id : แบบฟอร์มที่มีฟิลด์อัพโหลดไฟล์
  2. Download as Attachment: Whether or not to add "?attachedment=true" in link.

4. ผลลัพธ์และผลลัพธ์ที่คาดหวังจากปลั๊กอินของคุณคืออะไร?

ชื่อไฟล์จะปรากฏเป็นลิงค์ใน Datalist

5. มีทรัพยากร / API ใด ๆ ที่สามารถนำมาใช้ซ้ำได้?

คุณสามารถอ้างอิงถึง File Upload Field เกี่ยวกับวิธีสร้างลิงค์ดาวน์โหลดของไฟล์

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

เราจำเป็นต้องให้ซอร์สโค้ด Joget Workflow ของเราพร้อมและสร้างโดยทำตาม this guideline

บทช่วยสอนต่อไปนี้จัดทำขึ้นด้วย Macbook Pro และ Joget Source Code version 5.0.0. โปรดอ้างอิงถึง แนวทางสำหรับการพัฒนาปลั๊กอิน เพื่อคำสั่งแพลตฟอร์มอื่นๆ

ให้กล่าวว่าไดเรกทอรีโฟลเดอร์ของเราดังต่อไปนี้

- Home
  - joget
    - plugins
    - jw-community
      -5.0.0

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

เรียกใช้คำสั่งต่อไปนี้เพื่อสร้างโครงการ maven ในไดเรกทอรี "ปลั๊กอิน"

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

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

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

เราควรได้รับข้อความ "BUILD SUCCESS" ที่แสดงในเครื่องของเราและโฟลเดอร์ "file_link_datalist_formatter" ที่สร้างในโฟลเดอร์ "plugins"

เปิดโครงการ maven ด้วย IDE ที่คุณโปรดปราน เราแนะนำให้ใช้ NetBeans.  

7. เริ่มโค้ด!

a. การขยาย abstract class ของประเภทปลั๊กอิน

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

b. การดำเนินการของ abstract methods ทั้งหมด

เช่นเคยเราจะต้องใช้ abstract methods ทั้งหมด. เราจะใช้ AppPluginUtil.getMessage method เพื่อสนับสนุน i18n และใช้ตัวแปรคงที่ MESSAGE_PATH สำหรับ message resource bundle directory.

 

Implementation of all basic abstract methods
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."); 
    }
}

จากนั้นเราต้องทำ UI สำหรับผู้ใช้ผู้ดูแลระบบเพื่อให้อินพุตสำหรับปลั๊กอินของเรา ใน getPropertyOptions method, เราได้ระบุไฟล์ ตัวเลือกคุณสมบัติปลั๊กอิน ของเราไว้ที่ "/properties/fileLinkDatalistFormatter.json". ให้เราสร้าง directory "resources/properties" ภายใต้ "file_link_datalist_formatter/src/main" directory. หลังจากสร้าง directory, สร้างไฟล์ชื่อ "fileLinkDatalistFormatter.json" ในโฟลเดอร์ "properties" 

ในไฟล์ตัวเลือกคุณสมบัติ, เราจะต้องกำหนดตัวเลือกดังต่อไปนี้. โปรดทราบว่าเราสามารถใช้ "@@message.key@@" syntax เพื่อสนับสนุน i18n ในตัวเลือกคุณสมบัติของเรา

[{
    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 : ''
        }]
    }]
}]
 
เมื่อเราทำตัวเลือกคุณสมบัติเพื่อรวบรวมอินพุตแล้วเราสามารถทำงานกับวิธีหลักของปลั๊กอินซึ่งเป็นวิธีการจัดรูปแบบ

 

    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. จัดการ dependency libraries ของปลั๊กอินของคุณ

ปลั๊กอินของเราใช้คลาส org.displaytag.util.LookupUtil และมันจำเป็นต้องใช้ displaytag และ jsp-api library. ดังนั้นเราต้องเพิ่มในไฟล์ POM ของเรา

<!-- 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. ทำปลั๊กอิน internationalization (i18n) ของคุณให้พร้อม

เรากำลังใช้ i18n message key ใน getLabel และ getDescription method. เรายังใช้ i18n message key ในไฟตัวเลือกคุณสมบัติของเราด้วย. ดังนั้นเราจะต้องสร้างไฟล์ message resource bundle properties สำหรับปลั๊กอินของเรา

สร้าง directory "resources/messages" ภายใต้ "file_link_datalist_formatter/src/main" directory. จากนั้นสร้างไฟล์ "FileLinkDatalistFormatter.properties" ในโฟลเดอร์ ในไฟล์ตัวเลือกเราต้องเพิ่ม message keys และ label ดังต่อไปนี้

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. ลงทะเบียนปลั๊กอินของคุณืี่ Felix Framework

เราจะต้องลงทะเบียนคลาสปลั๊กอินของเราใน Activator class (Auto generated in the same class package) เพื่อบอก Felix Framework ว่านี่คือปลั๊กอิน

    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/.

 

  • No labels