闪亮的服务器自定义Handlebars.js模板 [英] Shiny Server custom Handlebars.js templates
问题描述
我完全不熟悉handlebars.js,但是我想自定义Shiny Server随附的目录索引模板.具体来说,我要做的是呈现不同应用程序缩略图的页面.
I'm not at all familiar with handlebars.js but I'd like to customize the directory index template that comes with Shiny Server. Specifically, what I'm looking to do is render a page of thumbnails of the different apps.
文件/opt/shiny-server/templates/directorIndex.html带有以下代码,该代码引用了许多表达式,包括{{title}},对应用程序,目录和文件的引用.
The file /opt/shiny-server/templates/directorIndex.html comes with the code below which reference a number of expressions including {{title}}, references to apps, dirs and files.
<!DOCTYPE html>
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{{title}}</title>
<link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro' rel='stylesheet' type='text/css'>
<style type="text/css">
body {
font-family: Helvetica, Arial, sans-serif;
background-color: #F5F5F5;
}
pre, tt, code, .code, #detail {
font-family: 'Consolas', 'Courier New', 'Courier', monospace;
}
h1 {
font-size: 40px;
}
a {
text-decoration: none;
}
</style>
</head>
<body>
<h1>{{title}}</h1>
<ul>
{{#each apps}}
<li><a class="code" href="{{this.url}}">{{this.name}}</a> (application)</li>
{{/each}}
{{#each dirs}}
<li><a class="code" href="{{this.url}}/">{{this.name}}</a></li>
{{/each}}
{{#each files}}
<li><a class="code" href="{{this.url}}">{{this.name}}</a></li>
{{/each}}
</ul>
</body>
</html>
所以我有两个问题.
首先-我怎么知道可以调用哪些表达式?
First - how can I know what expressions are available to call?
第二个-让我只有一个html页面(据我所知),我该如何注册一个助手,例如
Second - give that I just have this one html page (as far as I can tell) how do I register a helper, e.g.
Handlebars.registerHelper('splitURL', function(url) {
var t = url.split("/");
return t[1];
});
推荐答案
我同样希望自定义directoryIndex.html模板,并且同样缺乏有关可以使用哪些把手表达式的文档.我不是网络开发人员,因此此处的代码可能是垃圾,但效果很好.听起来您已经解决了问题,但是其他人可能会在这种方法中找到一些用处.每个应用程序的图像都保存在site_dir/images中.
I had the same desire to customize the directoryIndex.html template and enjoyed the same lack of documentation about what handlebars expressions could be used. I'm not a web developer so the code here is probably rubbish, but it works well enough. It sounds like you already solved your issue, but others may find some use in this approach. Images for each app are saved in site_dir/images.
directoryIndex.html:
directoryIndex.html:
<!DOCTYPE html>
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{{title}}</title>
<link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro' rel='stylesheet' type='text/css'>
<link href="main.css" rel="stylesheet">
<script type='text/javascript'>
function include(arr,obj) {
return(arr.indexOf(obj) != -1);
}
function updateView(data) {
//update title and heading
if ("title" in data) {
var host = document.location.hostname;
if (host in data.title) {
document.title = data.title[host];
document.getElementById("title").innerHTML = data.title[host];
} else if ("default" in data.title) {
document.title = data.title.default;
document.getElementById("title").innerHTML = data.title.default;
}
}
//hide cards (for directories like /images)
if ("ignore" in data) {
var element;
for (var i in data.ignore) {
if (element = document.getElementById("card_"+data.ignore[i])) {
element.parentNode.removeChild(element);
}
}
}
//update each shiny app if it has JSON data
if ("apps" in data) {
for (var item in data.apps) {
if (document.getElementById("card_"+item)) {
if ("img" in data.apps[item])
document.getElementById("img_"+item).src = "/images/" + data.apps[item].img;
if ("name" in data.apps[item])
document.getElementById("name_"+item).innerHTML = data.apps[item].name;
if ("desc" in data.apps[item])
document.getElementById("desc_"+item).innerHTML = data.apps[item].desc;
}
}
}
}
function loadJSON(url) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var data = JSON.parse(this.responseText);
updateView(data)
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
document.addEventListener("DOMContentLoaded", function() {
loadJSON("data.json");
});
</script>
</head>
<body>
<div id="title_bar">
<h1 id="title"></h1>
</div>
<div id="apps">
{{#each dirs}}
<div id="card_{{name}}" class="card" onclick="location.href='{{url}}';" style="cursor: pointer;">
<img id="img_{{name}}" src="" alt="{{name}}" onerror="if (this.src != '/images/missing.png') this.src = '/images/missing.png';">
<div class="container">
<h4 id="name_{{name}}">{{name}}</h4>
<p id="desc_{{name}}"></p>
</div>
</div>
{{/each}}
</div>
</body>
</html>
data.json(位于site_dir根目录中):
data.json (located in the site_dir root location):
{
"title": {
"default": "Shiny Server",
"dev_host": "Shiny Server (Development)",
"accp_host": "Shiny Server (Acceptance)",
"prod_host": "Shiny Server",
"dev_host.fully.qualified.name": "Shiny Server (Development)",
"accp_host.fully.qualified.name": "Shiny Server (Acceptance)",
"prod_host.fully.qualified.name": "Shiny Server"
},
"ignore": [ "app_4", "app_5", "images" ],
"apps": {
"app_1": {
"name": "app 1 name goes here",
"desc": "app 1 description goes here",
"img": "app1.png"
},
"app_2": {
"name": "app 2 name",
"desc": "app 2 desc",
"img": "app2.png"
},
"app_3": {
"name": "app 3 name",
"desc": "",
"img": "app3.png"
}
}
}
main.css(位于site_dir根目录中):
main.css (located in the site_dir root location):
body, html {
font-family: Helvetica, Arial, sans-serif;
background-color: #F5F5F5;
color: #114;
margin: 0;
padding: 0;
}
#title_bar {
height: 80px;
background-color: #3475b4;
overflow: hidden;
border-bottom: 1px solid #3475b3;
-moz-box-shadow: 0px 0px 10px 3px #BBC;
-webkit-box-shadow: 0px 0px 10px 3px #BBC;
box-shadow: 0px 0px 10px 3px #BBC;
}
#title_bar h1 {
margin: 14px auto .5em auto;
padding: .2em;
color: #EEE;
text-align: center;
}
#apps {
margin-top: 14px;
}
.card {
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
transition: 0.3s;
border-radius: 5px;
width: 300px;
margin: 10px;
display: inline-block;
vertical-align: top;
}
.card:hover {
box-shadow: 0 12px 24px 0 rgba(0,0,0,0.2);
}
.card img {
display: block;
margin: 0 auto;
max-width: 300px;
max-height: 250px;
}
.container {
padding: 2px 16px;
}
这篇关于闪亮的服务器自定义Handlebars.js模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!