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-οnclick="donate"
<button class="btn btn-default" data-οnclick="donate" type="button">Donate</button>
完成之后,就可以重新编译部署项目了。
在浏览器中点击按钮的话,会在控制台看到一条消息"donate successful"。
希望你会喜欢。
项目的源码在github上可以看到,方便你下载测试。