Đồ án Công nghệ Web và dịch vụ trực tuyến - Tạo giao diện với Velocity Template

- Velocity là 1 template engine có mã nguồn mở được phát triển bởi các lập trình viên trên khắp thế giới. Đây là dự án của Apache Software Foundation. Velocity sử dụng các template dựa trên Java (Java-based) để hợp nhất các mẫu. - 1 template engine là 1 phần mềm được thiết kế để xử lý các web templates và các thành phần thông tin để tạo ra các tài liệu web ( web documents) . Mọi velocity project bao gồm 2 thứ : velocity template và chương trình Java. - Chúng ta có thể tham chiếu các đối tượng được định nghĩa = mã Java với Velocity template language. Do đó, 1 Velocity template có thể được sử dụng tạo giao diện trong các ứng dụng web. Velocity sẽ giúp hoàn tất việc tách biệt giữa trình bày các layout và thực thi các business logic. - 1 veloctiy template là 1 file text có phần mở rộng là .vm , bao gồm các kí tự văn bản thường gặp và 1 số kí tự đặc biệt dùng trong velocity. Ví dụ : $name.

doc30 trang | Chia sẻ: tuandn | Lượt xem: 3682 | Lượt tải: 4download
Bạn đang xem trước 20 trang tài liệu Đồ án Công nghệ Web và dịch vụ trực tuyến - Tạo giao diện với Velocity Template, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Viện công nghệ thông tin và truyền thông Trường Đại học Bách Khoa Hà Nội ------------------------------------------------ ĐỒ ÁN: CÔNG NGHỆ WEB VÀ DỊCH VỤ TRỰC TUYẾN Nhóm 5 Đề tài 9 : Tạo giao diện với Velocity template. Giáo viên hướng dẫn: TS Tạ. Tuấn Anh Thành viên nhóm: Ngô Đức Chí shsv:20070311 – HTTT K52 Nguyễn Đắc Đồng shsv:20070813 – HTTT K52 Nguyễn Thành Công shsv:20070364 – HTTT K52 Lê Văn Đoàn shsv:20070777 – HTTT K52 MỤC LỤC Velocity template Tổng quan Velocity là 1 template engine có mã nguồn mở được phát triển bởi các lập trình viên trên khắp thế giới. Đây là dự án của Apache Software Foundation. Velocity sử dụng các template dựa trên Java (Java-based) để hợp nhất các mẫu. 1 template engine là 1 phần mềm được thiết kế để xử lý các web templates và các thành phần thông tin để tạo ra các tài liệu web ( web documents) . Mọi velocity project bao gồm 2 thứ : velocity template và chương trình Java. Chúng ta có thể tham chiếu các đối tượng được định nghĩa = mã Java với Velocity template language. Do đó, 1 Velocity template có thể được sử dụng tạo giao diện trong các ứng dụng web. Velocity sẽ giúp hoàn tất việc tách biệt giữa trình bày các layout và thực thi các business logic. 1 veloctiy template là 1 file text có phần mở rộng là .vm , bao gồm các kí tự văn bản thường gặp và 1 số kí tự đặc biệt dùng trong velocity. Ví dụ : $name. Velocity template language CÂU LỆNH VÀ THAM CHIẾU Dưới đây là 1 câu lệnh VTL: #set ($me = "Velocity") Một câu lệnh VTL bắt đầu với một dấu #. Từ “set” là để chỉ thị. Trong VTL, 1 tham chiếu bắt đầu với một ký tự $. Vì vậy, “$me” là một tham chiếu, hay là 1 biến tham chiếu trong trường hợp này. Biến “$me” được gán giá trị là “Velocity”. Velocity là một chuỗi. Trong VTL một chuỗi có thể kèm theo trong dấu nháy đơn hoặc kép. Một chuỗi trong dấu nháy đơn được được thể hiện trực tiếp trong khi một chuỗi trong dấu nháy kép có thể chứa các biến mà sẽ được thay thế bằng giá trị của chúng khi template được hợp thành. Có 1 cách khác để sử dụng các tham chiếu: $witness.getMessage() Ở đây chúng ta sử dụng một tham chiếu để gọi phương thức của một đối tượng đã được định nghĩa = mã Java và đã được thêm vào Velocity context. Công cụ template sẽ in ra một tin nhắn trả về bởi phương thức getMessage () của witness. CÂU ĐIỀU KIỆN Mọi ngôn ngữ kịch bản( dùng để báo cho chương trình cách thực hiện các thủ tục) đều có các câu lệnh điều kiện vì nguyên lý đó đã được xây dựng trong CPU. #if( $ihave > 199 ) Buy iPhone #elseif( $ihave == 199 ) Buy Nexus One #else Play volleyball #end Từ chỉ thị if kết thúc với từ chỉ thị end. Bạn có thể thấy nó, không cần quan tâm chúng ta đang có gì ở đây. LOOPS Trong VTL cũng có lặp. #foreach( $energy in $cleanEnergies ) $energy #end Nó sẽ in ra như sau: Solar energy Wind power Hyropower Geothermal energy Directives Từ chỉ thị include cho phép công cụ dùng để viết template import(nạp) vào 1 local file(tệp tin cục bộ). Các nội dung của local file sẽ được thêm vào template ở vị trí mà từ chỉ thị include được định nghĩa. Các nội dung của tệp tin sẽ được template engine hiểu. #include( "snippet.html" ) Chúng ta cũng có từ chỉ thị parse . Nó sẽ truyền cho tệp tin template(template file) 1 đối số. Template engine sẽ phân tích template file và trả ra nội dung của nó. Đây là câu lệnh: #parse ("navigation.vm") Câu lệnh này sẽ trả ra the navigation.vm template. Từ chỉ thị stop dừng việc running của template engine. Nó có thể được dùng cho mục đích debug : #stop VELOCIMACROS Các Velocity templates trong Liferay cũng sử dụng Velocity macros để gọi Velocimacros. Một Velocimacro là 1 hàm nhỏ trong VTL. Nó có thể sử dụng để xử lý các xâu. Nó lấy các tham số làm đầu vào và in ra text. Nó không trả ra giá trị. A template developer có thể sử dụng từ chỉ thị macro để viết 1 Velocimacro, nó có thể được sử dụng nhiều lần trong 1 Velocity template. #macro (printSwimmingPools $val) #if ($val ) #foreach ($e in $val) $e #end #end #end Còn đây là cách làm thế nào để sử dụng Velocimacro trên trong 1 template: #set( $nemoSwimmingPools = ["The Pacific Ocean","The Atlantic Ocean","The Indian Ocean"] ) #printSwimmingPools( $nemoSwimmingPools ) Thường thì các Velocimacros được định nghĩa trong 1 file gọi là VM_global_library.vm (Đây là trường hợp dùng trong Liferay). Đồng thời, Liferay sử dụng ${PORTAL_SRC_HOME}/portal-impl/src/VM_liferay.vm của chính nó để tạo Velocimacros của nó. Trong Liferay, các thuộc tính của Velocity được thiết lập trong file ${PORTAL_SRC_HOME}/portal-impl/src/portal.properties (Sau khi biên dịch, file portal.properties này sẽ nằm trong file ${AS_ROOT_HOME}/WEB-INF/lib/portal-impl.jar ): velocity.engine.velocimacro.library=VM_global_library.vm,VM_liferay.vm CHÚ THÍCH Đây là 1 điều khác mà bạn sẽ biết về VTL – làm thế nào để thêm các dòng chú thích. ## single line comment. #* multi-line comment. *# Trong 1 Velocity template, các dòng này sẽ được Velocity engine bỏ qua và không hiện ra trên portal page. Người dùng sẽ không thấy chúng. Để có thêm thông tin về VTL, bạn có thể tham khảo Velocity User Guide at Velocity template trong Liferay Velocity và Liferay Tại sao Velocity là template mặc định của Liferay Velocity template là template được mặc định trong Liferay.( Liferay còn có 1 template nữa là Free Maker). Vậy tại sao Liferay không lựa chọn Free Maker làm template mặc định cho mình? Lí do là: Free Maker chỉ mới được hỗ trợ trong Liferay và chưa được kiểm tra kĩ lưỡng. Các Liferay developers đã quá quen thuộc với Velocity, họ cho rằng “ It is core to Liferay”. Thế nên việc thay đổi là không hề dễ dàng. Tuy nhiên thì, Free Maker cũng có 1 số ưu thế: Một số người “quyền lực” trong Liferay và nhiều developers rất nhiệt tình với Free Maker. Hầu hết những gì Velocity làm được thì Free Maker cũng làm được. Free Maker có 1 số ưu điểm so với Velocity. Ví dụ, trong Velocity, có khó khăn khi truy cập vào các thuộc tính tĩnh (static fields), còn trong Free Maker thì không, … thế nên nhiều developers đã lựa chọn Free Maker để tạo source code cho mình. Rất có thể trong tương lai, Free Maker sẽ thay thế cho Velocity trong Liferay. Velocity template được sử dụng trong ba vị trí trong mô hình Liferay : Theme Portlet Web content Các Velocity template mặc định trong Liferay Mặc định trong Liferay có 5 file Velocity template được tạo ra khi triển khai 1 theme gồm : init_custom.vm : file này cho phép bạn ghi đè và định nghĩa các biến velocity mới. navigation.vm : file này được gọi từ portal_normal.vm và cung cấp HTML để tạo các navigation menus. portal_normal.vm : file này điều khiển khung HTML cơ bản của trang mà Liferay sẽ phục vụ. portal_pop_up.vm : file này điều khiển layout của các portal templates dành cho thông báo dạng pop-up. porlet.vm : file này gói các phần của mọi porlet. init_custom.vm Trong file này, bạn có thể khai báo mọi biến sử dụng trong portal_normal.vm . + Khai báo 1 biến velocity mới ( ở trên là $any_custom_name) để sử dụng cho theme. + Có thể ghi đè giá trị của các biến velocity đã có ( như ở trên là $company_name ) nếu bạn có biến cùng tên ở đây. Ví dụ: #set ($theme_name = "palm-tree-publications-theme") #set ($the_title = "Palm Tree Publications Theme") #set ($company_name = "Palm Tree Publications Inc.") #set ($community_name = "Palm Tree Publication Reviewers") #set ($any_custom_name = "This is just a sample custom name") portal_normal.vm Đây là file chính để phục vụ , giống như là main frame của template. Mọi biến mới hoặc đã tồn tại được định nghĩa trong file init_custom.vm có thể được gọi trong file này. Bạn có thể thêm mới hoặc thay đổi các mã HTML hoặc gọi các định nghĩa CSS trong file này hoàn tất thiết kế của bạn. Ví dụ, bạn có thể muốn thay đổi hiển thị nội dung và/hoặc look and feel của các vùng header hoặc footer. Để tùy biến footer , ta thay đổi mã giữa 2 thẻ , đó là các phần tử HTML5. Nếu cần thêm 1 velocity template mới, như là docroot/_diffs/templates/any_custom_velocity_file.vm => dòng dưới đây sẽ được thêm vào file portal_normal.vm : #parse ("$full_templates_path/any_custom_velocity_file.vm") navigation.vm Navigation template được gọi trong file portal_normal.vm , để hiển thị navigation menu: #if ($has_navigation) #parse ("$full_templates_path/navigation.vm") #end Thay đổi file navigation.vm để thay đổi hiển thị của navigation menu. porlet.vm Template này xác định làm thế nào 1 porlet chuẩn được đưa ra trên 1 trang portal. Nó được gọi trong portal_normal.vm: $theme.wrapPortlet("portlet.vm", $content_include) Có thể thêm các tính năng khác , như các print và help icon, hoặc xóa 1 số icons có sẵn như minimize, maximize hoặc close trong file porlet.vm . Ghi nhớ rằng thay đổi trên sẽ sẽ áp dụng cho tất cả các trang sử dụng theme này. Có thể xem các Velocity tags có thể sử dụng cho theme trong file: ${liferay.portal.src.dir}\util-taglib\src\com\liferay\taglib\util\VelocityTaglib.java Mỗi phương thức trong file này có thể sử dụng trong theme như 1 Velocity tag , phương thức có dạng : $theme.{method.name}. ví dụ như: $theme.iconOptions() $theme.iconMinimize() $theme.iconMaximize() $theme.iconClose() $theme.iconPortlet() $theme.search() portal_pop_up.vm File này có đường dẫn : /docroot/_diffs/templates/portal_pop_up.vm . File này được sử dụng để tùy biến look and feel của các cửa sổ thông báo dạng pop-up. Đối với các Velocity template trong Liferay, chúng ta có thể: Thêm 1 template mới để nó được gọi bởi file portal_normal.vm. Mỗi template phụ trách 1 số thành phần nào đó của theme. Nếu muốn thêm 1 số thành phần mới hay thông tin phụ, chỉ việc tạo 1 template mới và thêm nó vào file portal_normal.vm hoặc file portal_popup.vm. Thay đổi các file template đã có. O Thay đổi các giá trị tham số của Velocity trong file init_custom.vm O Thay đổi nội dung trong các template hỗ trợ ví dụ như file navigator.vm và portlet.vm O Thêm một portlet trong một template sẽ hiển thị trong theme Tạo giao diện với Velocity template Velocity template trong themes 1.1 Tại sao, khi nào dùng Velocity template trong theme Câu hỏi đặt ra là: để tùy chỉnh themes, bạn có thể kéo thả các portlet và đặt vào vị trí nào đó mình muốn trong theme, như vậy dễ dàng, nhanh và trực quan hơn rất nhiều. Vậy tại sao lại sử dụng Velocity template, phải sửa code , rồi thực thi lại theme… Trả lời: Việc kéo thả các portlet chỉ áp dụng cho trang web hiện tại đang dùng theme đó, chứ không phải áp dụng cho theme, không thể chỉnh sửa thực sự được theme đó. Nếu như 1 portlet cần phải nhúng nhiều lần, mỗi lần tạo 1 trang web bạn lại phải kéo thả portlet đó vào trong theme của trang web đó. Sẽ rất mất công làm đi làm lại. Bằng việc sử Velocity template, bạn có thể sửa theme thực sự, theme sau khi được chỉnh sửa đó có thể áp dụng cho mọi trang web sau này sử dụng themes đó. Việc nhúng portlet chỉ làm 1 lần mà vẫn được áp dụng nhiều lần, bất kì khi nào sử dụng themes đã chỉnh sửa. Vậy, chúng ta sử dụng Velocity template tùy biến theme khi: Phải sử dụng 1 theme nào đó nhiều lần, và trong theme đó có 1 số portlet phải dùng lại nhiều lần => sử dụng Velocity template để nhúng “cố định” các portlet cần dùng vào theme đó. 1.2 Áp dụng Velocity template trong theme Chúng ta có thể tùy biến theme thông qua Velocity template. Sử dụng các Velocity template đã có hoặc tạo template mới để: Thêm vào 1 thành phần giao diện thông qua 1 template. Nhúng 1 porlet vào trong theme. Sử dụng các Liferay service qua Velocity template. 1.2.1 Thêm 1 thành phần giao diện vào theme Chúng ta có thể thêm nhiều thành phần giao diện vào trong theme thông qua 1 template. Ví như 1 ô tìm kiếm, hay 1 danh sách đường link tới các trang khác với tùy chỉnh hiển thị bằng CSS, … Chúng ta đi vào ví dụ cụ thể: Ở đây chúng ta thêm vào theme : 1 ô tìm kiếm và 1 danh sách các đường link ở cuối trang. Đầu tiên chúng ta tạo và triển khai 1 theme nào đó. Ở đây tạo và triển khai theme Noir: Chạy lệnh create.bat noir Noir sau khi từ màn hình cmd đã vào đường dẫn PLUGINS_SDK_HOME}/themes/ . Câu lệnh này sẽ tạo một theme có tên là Noir. Trong thư mục theme, thư mục con noir-theme sẽ được tạo. Sao chép các thư mục css, images, js và templates vào folder _diffs theo đường dẫn ${PLUGINS_SDK_HOME}/themes/noir-theme/docroot/_diffs/ Chạy lệnh ant deploy trong đường dẫn ${PLUGINS_SDK_HOME}/themes/noir-theme/ Một theme Noir đã được tạo và triển khai (deploy). Chúng ta có thể thêm 1 ô tìm kiếm vào theme này 1 cách rất đơn giản như sau: Thêm đoạn mã sau vào template portal_normal.vm : $theme.journalContentSearch() Trong đoạn code trên: $theme là biến tham chiếu đến đối tượng theme, là đối tượng của lớp com.liferay.portal.model.Theme journalContentSearch() là 1 phương thức của đối tượng theme Đoạn mã trên được viết với một thẻ . Nó sẽ tạo ra một hộp tìm kiếm nội dung web. Bạn có thể nhập vào một từ khóa trong hộp đó và ấn phím Enter để tìm kiếm nội dung web theo từ khóa. Hiển thị 1 số link đến các trang khác ở cuối trang: Thêm vào đoạn mã sau vào template portal_normal.vm: #parse ("$full_templates_path/bottom_navigator.vm") Đoạn mã trên sẽ phân tích một file bottom_navigator.vm, mà đầu ra là một danh sách không sắp xếp các đường link. Danh sách này sau đó sẽ được chuyển đổi thành các dòng văn bản thông qua CSS. Chúng ta sẽ thêm một file bottom_navigator.vm trong thư mục templates theo đường dẫn ${PLUGINS_SDK_HOME}/themes/noir-theme/docroot/_diffs/templates. Nội dung của nó như sau : #foreach ($nav_item in $nav_items) #if ($nav_item.isSelected()) #set ($nav_item_class = "selected") #else #set ($nav_item_class = "") #end $nav_item.getName() #end Chúng ta thêm một vài đoạn mã CSS vào trong file custom.css theo đường link sau ${PLUGINS_SDK_HOME}/themes/noir-theme/docroot/_diff/css/custom.css : #footer { background: url(../images/calendar/day_heading.png) no-repeat; color: #739ABE; height: 106px; position: relative; width: 962px; } Và đây là kết quả: 1.2.2 Nhúng 1 portlet sẵn có vào trong theme Đôi khi việc chúng ta nhúng một portlet sẵn có vào một theme là cần thiết. Chúng ta có thể nhúng một portlet trong một theme thông qua một template Velocity nào đó như portal_normal.vm. Portlet đã được nhúng thường chứa một lượng thông tin khá nhỏ.Ví dụ như đó có thể là màn hình đăng nhập. Nó cũng có thể được dùng để hiển thị một số tùy chỉnh nội dung động. Chúng ta thực hiện các bước dưới đây để thêm một portlet vào một theme : Tạo một portlet Embed và thực thi nó. Trong cmd, chỉ đường dẫn tới ${PLUGINS_SDK_HOME}/portlets/ Chạy câu lệnh create embed Embed , 1 folder embed-portlet sẽ được tạo ra. Chỉ đường dẫn tới thư mục vừa tạo: ${PLUGINS_SDK_HOME}/portlets/embed-portlet/ . Chạy câu lệnh ant deploy . Portlet Embed vừa tạo đã được thực thi. Trong file portal_normal.vm của theme Noir theme, thêm đoạn mã sau : $theme.runtime("embed_WAR_embedportlet_INSTANCE_6CMo") Tổng quát của khai báo nhúng 1 portlet vào trong 1 theme là: $theme.runtime(portlet.id) Việc chúng ta phải quan tâm là làm thế nào để lấy được portlet.id của 1 portlet? Ta làm như sau: - Nhúng 1 portlet(portlet đang cần tìm id) vào trong trang nào đó (kéo,thả). Trong khung của portlet cần tìm chọn Configuration -> Sharing. Tìm portletid Để dễ hình dung, ta có ví dụ sau: Portlet Hi đã được tạo sẵn. Kéo thả vào 1 trang nào đó. Chọn phần Configuration Chọn thẻ sharing, và tìm id của portlet. Như trong hình vẽ, portletid của portlet Hi là : hi_War_hiportlet_INSTANCE_18qD Sau khi đã nhúng portlet xong, ta xem kết quả: Thực thi lại theme Noir và tải lại trang tin. Portlet được nhúng sẽ hiển thị với các đường bao ngoài. Và đôi khi đường bao ngoài sẽ làm cho việc hiển thị trang web không được đẹp, vậy nên ta có thể tùy chỉnh, bỏ đi đường bao ngoài của portlet vừa nhúng vào theme. Click vào biểu tượng thiết lập cấu hình trên portlet Embed . Click vào Look and Feel. Bỏ dấu tích ở ô Show Borders và click vào nút Save. Đóng cửa sổ Look and Feel và tải lại trang- các đường bo ngoài của portlet đã được bỏ đi, chỉnh sửa cho portlet được nhúng đã hoàn chỉnh. Bạn có thể nhìn thấy dòng This is the Embed portlet trên đầu trang, đó là dòng được hiển thị bởi portlet Embed. Bạn có thể cấu hình file portlet.xml ${PLUGINS_SDK_HOME}/portlets/embed-portlet/docroot/WEB-INF/portlet.xml như sau để bỏ đi đường viền : portlet-setup-show-borders false Kết quả là: Sau khi bỏ đường bao ngoài: Hiển nhiên là bạn có thể nhúng nhiều portlet vào cùng một theme. 1.2.3 Sử dụng Liferay services Có nhiều tính năng mạnh mẽ chúng ta có thể sử dụng trong Velocity templates, điển hình là những dịch vụ Liferay. Những dịch vụ cuả Liferay có thể được sử dụng để truy cập nhiều tài nguyên từ cổng kết nối. #set($layoutService=serviceLocator.findService("com.liferay.portal.service.LayoutLocalService")) #set($layouts=layoutService.getLayouts($layout.getGroup().getGroupId(), false)) #foreach ($page in $layouts) $page.getName($locale) | #end Ví dụ, ta sẽ thử sử dụng LayoutLocalService. Dưới đây là code : Copy đoạn trích code và paste ở chỗ phù hợp trong file portal_normal.vm. Khi chạy, nó sẽ in ra tên của tất cả những public web (các trang với cho phép mọi người đều có thể truy nhâp) trong tập các web. Tên của các trang web sẽ được phân định bằng 1 thanh đứng. Velocity không có chức năng xử lí các trường hợp ngoại lệ trong khi nhiều dịch vụ Liferay khác cũng bỏ qua các ngoại lệ này. Để bù lại, Liferay đã đưa ra một phương thức là findExceptionSafeService dành cho đối tượng $serviceLocator .Vậy nên, ta có thể làm như sau : #set($layoutService=$serviceLocator.findExceptionSafeService("com.liferay.portal.service.LayoutLocalService")) Khi ta sử dụng phương thức này, nếu 1 ngoại lệ bị bỏ qua trong $layoutService, nó sẽ ko thể phá hỏng Velocity engine. Phương thức findExceptionSafeService đã gói gọn hết những dịch vụ cơ bản với 1 proxy, nó sẽ bắt các ngoại lệ và trả lại giá trị null. Velocity trong portlet Tạo 1 portlet với Velocity và sử dụng nó Có rất nhiều cách sử dụng Velocity templates. Ví dụ, ta có thể sử dụng 1 Velocity template để tạo body của 1 email. Ta đặt phần body của email trong 1 templates thay cho việc tạo hard-coding (cốt cứng) trong Java. Ta cũng đặt tên người gửi và địa chỉ email của họ trong file portlet.properties. - Chạy creat.bat vmail Vmail trong thư mục ${ PLUGINS_SDK_HOME}/portets/ - Tạo 1 template ${PLUGINS_SDK_HOME}/potlets/vmail-portlet/docroot/WEB-INF/src/com/sample/jsp/portlet/etemplate.vm có nội dung như sau: Thank you for your exellent work on $company.get ProjectName () for $company.getCompanyName () -Tạo 1 file {PLUGINS_SDK_HOME}/portlets/vmail-portlet/docroot/ WEB-INF/src/com/sample/jsp/portlet/JSPPortlet.java với nội dung như sau: String template = StringUtil.read(getClass().getClassLoader(), "com/sample/jsp/portlet/etemplate.vm", false); Ecompany eCom = new Ecompany(); variables.put("company", eCom); String fromAddress = PortletProps.get("fromEmailAddr"); String body = Velocity.evaluate(velocityContext, strWriter, JSPPortlet.class.getName(),template); String toEmailAddr = ParamUtil.getString(actionRequest, "emailAddr"); InternetAddress from = new InternetAddress(fromAddress, fromName); MailServiceUtil.sendEmail(message); - Thêm đoạn mã dưới đây vào file ${PLUGINS_SDK_HOME}/portlets/vmail-portlet/docroot/view.jsp: " method="post" name="fm1"> - Triển khai porlet Vmail. Code đọc trong email template com/sample/jsp/portlet/etemplate.vm là 1 chuỗi. Một đối tượng com.sample.jsp.portlet.Ecompany được khởi tạo và được đặt trong đối tượng java.util.Map . Đối tượng java.util.Map và chuỗi kí tự mẫu được truyền vào Velocity engine để hoàn tất mọi việc. Chuỗi văn bản mẫu được gửi tới người dùng chính là phần body text của email. Tên và địa chỉ hòm thư của người dùng được lấy từ giao điện người dùng. Sau khi thêm Vmail portlet vào 1 trang, bạn sẽ thấy Sau khi bạn gõ username và địa chỉ email, click nút Submit, 1 email sẽ được gửi đến