Sails内置了ejs模板引擎来完成View层的渲染。
ejs模板文件都放在views文件夹下进行维护,主要分为两种类型layout与page,layout主要是共享用的布局文件,page是真正的页面body内容。Sails默认提供了指定ejs模板引擎的layout功能。
assets目录是Sails应用下放置前端静态资源的目录,比如js、css、image等。
在前面Controller层的案例中,我们已经写出了一个View层的例子,下面我们介绍一下Sails View层的一些其他特性:
Sails View层可以通过在route中定义locals属性的方式,将ViewModel数据传入模板引擎用于渲染页面。
比如,建立一个pages/locals.ejs:
<div>
<h1>Welcome <%= user.username %>h1>
div>
于是,我们就可以在route中定义一个路由如下:
'/locals': {
view: 'pages/locals',
locals: {
user: {
username: 'xreztento'
}
},
},
访问:http://127.0.0.1:1337/locals
可以看到我们已经完成了ViewModel的传递,除了简单的字符串以外,还可以传递如html或js脚本这样的数据,比如我们修改一下pages/locals.ejs:
<div>
<h1>Welcome <%= user.username %>h1>
<div><%- someRawHTML %>div>
<div><%- someXSS %>div>
div>
route:
'/locals': {
view: 'pages/locals',
locals: {
user: {
username: 'xreztento'
},
someRawHTML: '',
someXSS: ''
},
},
Sails提供了exposeLocalsToBrowser来将ViewModel中的属性暴露给浏览器:
<%- exposeLocalsToBrowser({keys:['someRawHTML', 'someXSS']}) %>
<div>
<h1>Welcome <%= user.username %>h1>
<div><%- someRawHTML %>div>
<div><%- someXSS %>div>
div>
<script type="text/javascript">
console.log(window.SAILS_LOCALS.someRawHTML);
console.log(window.SAILS_LOCALS.someXSS);
script>
ViewModel中包含html和js脚本意味着可能会发生被XSS攻击的风险,因此,我们可以将模板进行以下修改:
<%- exposeLocalsToBrowser({keys:['someRawHTML', 'someXSS'], dontUnescapeOnClient: true}) %>
<div>
<h1>Welcome <%= user.username %>h1>
<div id="someRawHTML">div>
<div id="someXSS">div>
div>
<script type="text/javascript">
document.querySelector("#someRawHTML").innerHTML = window.SAILS_LOCALS.someRawHTML;
document.querySelector("#someXSS").innerHTML = window.SAILS_LOCALS.someXSS;
script>
Sails为内置的ejs引擎提供了便捷的指定layout的方式,可以在route时在locals中设置layout属性来指定使用的layout,如:
'get /privacy': {
view: 'users/privacy',
locals: {
layout: 'users'
}
},
这部分可以参考之前的使用案例。
Sails为内置的ejs引擎提供了便捷的模板代码复用方式partials,核心语法是:
<%- partial(relPathToPartial, optionalOverrides) %>
我们在views下新建partials目录,并创建navbar.ejs:
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Navbara>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarText"
aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon">span>
button>
<div class="collapse navbar-collapse" id="navbarText">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)span>a>
li>
<li class="nav-item">
<a class="nav-link" href="#">Featuresa>
li>
<li class="nav-item">
<a class="nav-link" href="#">Pricinga>
li>
ul>
<span class="navbar-text">
<%= username %>
span>
div>
nav>
修改locals.ejs:
<%- partial ('../partials/navbar.ejs', { username: user.username }) %>
<div>
<h1>Welcome <%= user.username %>h1>
div>
于是我们就完成了两个部分ejs模板的合并。