Liferay DXP的portlet支持soy模板。通過soy模板我們可以利用Google Closure來創建豐富的web應用。
接下來我將帶領你來領略soy portlet的風騷。
所需工具:
Liferay IDE 3.1. -- Liferay官方工具,用來創建portlet項目和運行gradle任務。
Atom Editor. -- 專業的UI開發編輯工具。你也可以使用你管用的工具。
所需相關知識:
熟悉Liferay OSGi portlet module開發。如果你不熟悉的話,可以參考這個博客來學習如何創建mvc
portlet。
第1步: 使用soy框架創建portlet
我們先利用mvc項目模板創建一個mvc portlet module。這裏我命名項目爲sample-soy
和mvc portlet不同的是,我們的soy portlet類繼承與com.liferay.portal.portlet.bridge.soy.SoyPortlet類, 它其實也是MVCPortlet的子類。
將父類改名爲SoyPoetlet
這裏需要在build.gradle中添加依賴。
compileOnly group: "com.liferay", name: "com.liferay.portal.portlet.bridge.soy", version: "3.0.0"
然後將類的註解改成這樣:
@Component( immediate = true, property = { "com.liferay.portlet.add-default-resource=true", "com.liferay.portlet.application-type=full-page-application", "com.liferay.portlet.application-type=widget", "com.liferay.portlet.css-class-wrapper=table-wrapper", "com.liferay.portlet.display-category=category.sample", "com.liferay.portlet.header-portlet-css=/SoySample.css", "com.liferay.portlet.layout-cacheable=true", "com.liferay.portlet.preferences-owned-by-group=true", "com.liferay.portlet.private-request-attributes=false", "com.liferay.portlet.private-session-attributes=false", "com.liferay.portlet.render-weight=50", "com.liferay.portlet.scopeable=true", "com.liferay.portlet.use-default-template=true", "javax.portlet.display-name=Soy Sample Portlet", "javax.portlet.expiration-cache=0", "javax.portlet.init-param.copy-request-parameters=true", "javax.portlet.init-param.template-path=/", "javax.portlet.init-param.view-template=SoySample", "javax.portlet.name=soy_sample_portlet", "javax.portlet.resource-bundle=content.Language", "javax.portlet.security-role-ref=guest,power-user,user", "javax.portlet.supports.mime-type=text/html" }, service = Portlet.class )
根據這個註解,我們需要SoySample.soy作爲默認的顯示頁面。我們也會使用SoySample.scss作爲portlet的樣式文件。
第2步:NodeJS配置文件
我們會使用NodeJS來編譯我們的UI元素,例如soy,metal和其他js,css文件。
在項目根目錄下創建package.json文件,內容如下:
{
"dependencies": { "metal-component": "^2.10.0", "metal-soy": "^2.10.0" }, "devDependencies": { "liferay-module-config-generator": "^1.2.1", "metal-cli": "^4.0.1" }, "name": "soy-sample", "version": "1.0.0" }
將這個version和bnd.bnd中的version對應是一個很好的習慣。
第3步: 配置OSGi
將下面的代碼添加到bnd.bnd中,這樣bnd就會將package.jso包含進最終的jar文件中了,並且OSGi bundle需要soy capability。
Include-Resource: package.json Require-Capability: soy;filter:="(type=metal)"
第4步,使用render方法定義所需變量
添加/修改 portlet類中的render方法
@Override public void render( RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException { template.put("msg", "Good Job!"); super.render(renderRequest, renderResponse); }
我們會在soy模板中引用這個參數,並且顯示值爲"Good Job!"。
第5步,創建SoySample模板
在 src/main/resources/META-INF/resources/resources路徑下創建文件SoySample.soy文件,內容如下:
{namespace SoySample} /** * Show portlet message in the view. * @param id * @param msg */ {template .render} <div id="{$id}"> <div class="form-group"> <div class="input-group"> <span class="input-group-addon" id="inputGroupAddon01">Message:</span> <input aria-describedby="inputGroupAddon01" class="form-control" value="{$msg}" type="text"> </div> </div> <div class="form-group"> <div class="input-group"> <input aria-describedby="inputGroupAddon02" class="form-control" placeholder="Recipient's username, ex. neil.jin ;)" type="text"> <span class="input-group-addon" id="inputGroupAddon02">@liferay.com</span> </div> </div> <div class="form-group"> <div class="input-group"> <span class="input-group-addon">$</span> <input aria-label="Amount" class="form-control" type="text"> <span class="input-group-addon">.00</span> </div> </div> <div class="form-group"> <button class="btn btn-default" type="button">Donate</button> </div> </div> {/template}
Closure需要模板聲明使用類似java-doc註釋式的聲明。{templlate .render}聲明式必要的。並且,所有定義的參數必須要在模板中使用,這也防止了定義無用的變量。
而且{template .render} 前面不能有空格。
每次修改完soy文件,最好運行 build soy任務重新生成soy.js文件。
在我的模板中,我使用了lexicon來創建前端,這樣兼容性和用戶體驗可以達到最佳,並且節省代碼。
在相同文件夾中創建一個SoySample.scss文件,內容可以留空。
運行gradle任務buildSoy。
第6步,運行測試
現在可以編譯並且部署jar到Liferay服務器進行測試了。
如果沒什麼問題的話,就會顯示這樣的界面。
第一次編譯的時候,任務需要下載所需的node模塊,可能需要等一會,node_module文件夾大概100多M。
有時候在npmInstall的時候會卡死,可以停止運行任務,再重新編譯就好了。
第7步 javascript
接下來我會爲我的soy模板添加javascript。
在SoySample.soy相同的目錄下創建一個SoySample.es.js文件,內容如下:
import Component from 'metal-component/src/Component'; import core from 'metal/src/core'; import dom from 'metal-dom/src/dom'; import Soy from 'metal-soy/src/Soy'; import templates from './SoySample.soy';
class SoySample extends Component {
}
//Register component Soy.register(SoySample, templates);
export default SoySample;
這樣JS的框架就完成了。
第8步:添加javascript方法
接下來我們會創建一個donate方法,並且在瀏覽器控制檯顯示一條消息。
將下面的方法加入到SoySample類中:
/** * donate to neil * * @param {MouseEvent} event */ donate(event) { console.log("donate successful"); }
第9步,使用方法
我們會在用戶點擊donate按鈕的時候觸發這個方法,所以在donate按鈕中添加data-onclick="donate"
<button class="btn btn-default" data-onclick="donate" type="button">Donate</button>
完成之後,就可以重新編譯部署項目了。
在瀏覽器中點擊按鈕的話,會在控制檯看到一條消息"donate successful"。
希望你會喜歡。
項目的源碼在github上可以看到,方便你下載測試。