过滤Jade/Node.js中的降价内容
尊敬的黑客们 我希望在Jade模板中过滤一个满是标记的字符串。 我在一个变量中有降价 Jade在降价中插入一个变量非常好: 这:过滤Jade/Node.js中的降价内容,node.js,pug,Node.js,Pug,尊敬的黑客们 我希望在Jade模板中过滤一个满是标记的字符串。 我在一个变量中有降价 Jade在降价中插入一个变量非常好: 这: var jade=require('jade'); 变量jade_字符串=[ “:降价”, “这是降价!”, "第一",, “*#{var2}”, “*第三” ].join('\n'); var fn=jade.compile(jade_字符串,{pretty:true}); log(fn({var1:“First!”,var2:“Second!”); 由此产生:
var jade=require('jade');
变量jade_字符串=[
“:降价”,
“这是降价!”,
"第一",,
“*#{var2}”,
“*第三”
].join('\n');
var fn=jade.compile(jade_字符串,{pretty:true});
log(fn({var1:“First!”,var2:“Second!”);
由此产生:
这是降价!
- 首先
- 第二李>
- 第三
但是,我得到的是变量内部的实际完整标记。
这是:
var jade=require('jade');
变量jade_字符串=[
“div.markedup”,
“:降价”,
“\\{var2}”
].join('\n');
var fn=jade.compile(jade_字符串,{pretty:true});
var降价=[
“我被标记了!”,
“*1”,
“*两个”
].join('\n');
log(fn({var1:First!”,var2:markdown});
仅提供以下内容:
我被标记了!
*一个
*两个
因此,在我看来,Jade在执行任何变量之前都会过滤块
插值,然后在生成的HTML中插值变量。这是
如果你想用降价的方式写模板的话,这很好,但这并不多
如果您想以降价方式编写内容,请提供帮助
我知道我可以通过更多的编程来解决这个问题,但我觉得我
一定是遗漏了什么。毕竟,在
一个数据库,并将生成的HTML片段填充到模板中
最明显的用例是:标记过滤器
在Jade中有没有“正常”的方法
非常感谢即将到来的启示。我想答案是更多的编程,但我会告诉你我在做什么。我使用定制中间件,让我在最终的HTML文档输出之前组合任意转换过程。例如,我的middleware.js模块中有以下过滤器,我将依次解释
因此,简单的视图只需使用普通的jade,以及它对markdown、javascript和coffeescript的各种过滤器。有些视图,例如博客文章,需要更复杂的中间件链,如下所示
首先,根据请求,我建立了保存此响应核心内容的文件,并将其设置为res.viewPath
上的属性。这可以是原始HTML片段文件或标记文件。然后,我通过一系列中间件转换发送响应。我使用res.html
和res.dom
来存储正在构建的响应的中间表示
这一个只存储原始HTML(只是一个没有头部或布局的文档体片段)
这将把一个标记文件转换为HTML(使用标记js模块)
我有一个子版面,在我的主版面内,但在每个博客文章周围。因此,我将博客文章包装在这里的子版面中。(未显示的单独代码从json元数据文件生成res.post
对象)
现在,我围绕HTML的主要内容包装我的布局。请注意,我可以在这里设置页面标题之类的内容,或者等到以后,因为在此之后我可以通过jsdom操作响应。我会执行body:res.html | |“
,这样我就可以渲染一个空布局,然后如果方便的话插入body
exports.layout = function(req, res, next) {
var layoutPath;
layoutPath = path.join(__dirname, "..", "templates", "layout.jade");
return fs.readFile(layoutPath, "utf8", function(error, jadeText) {
var layoutFunc, locals;
layoutFunc = jade.compile(jadeText, {
filename: layoutPath
});
locals = {
config: config,
title: "",
body: res.html || ""
};
res.html = layoutFunc(locals);
return next(error);
});
};
这就是真正强大的东西的来源。我将HTML字符串转换为jsdom文档对象模型,该模型允许在服务器端进行基于jQuery的转换。下面的toMarkup
函数只允许我在不使用额外的
标记的情况下返回HTML,这是jsdom添加的内存jquery
exports.domify = function(req, res, next) {
return jsdom.env(res.html, [jqueryPath], function(error, dom) {
if (error) return next(error);
res.dom = dom;
dom.toMarkup = function() {
this.window.$("script").last().remove();
return this.window.document.doctype + this.window.document.innerHTML;
};
return next(error);
});
};
这是我做的一个自定义转换。这可以用真正有效的HTML替换像
这样的DSL标签,否则这将是一个很大的讨厌的
样板文件,我必须在每个博客文章中复制,如果flickr曾经更改过他们使用的样板文件标记,那么在许多博客文章标记文件中修复它将是一个维护难题。他们当前使用的样板文件位于flickrshowTemplate
变量中,并包含一些小胡子占位符{url}
exports.flickr = function(req, res, next) {
var $ = res.dom.window.$;
$("flickrshow").each(function(index, elem) {
var $elem, URLs;
$elem = $(elem);
URLs = $elem.attr("href");
return $elem.replaceWith(flickrshowTemplate.replace(/\{URLs\}/g, URLs));
});
return next();
};
嵌入youtube视频也一样<代码>
现在,如果需要,我可以更改标题,添加/删除javascripts或样式表,等等。在这里,我在布局已经呈现之后设置标题
postTitle = function(req, res, next) {
var $;
$ = res.dom.window.$;
$("title").text(res.post.title + " | Peter Lyons");
return next();
};
好的,现在回到最后的HTML
exports.undomify = function(req, res, next) {
res.html = res.dom.toMarkup();
return next();
};
现在我们把它运走
exports.send = function(req, res) {
return res.send(res.html);
};
为了把它们按顺序联系在一起,并让他们快速使用,我们确实这样做了
postMiddleware = [
loadPost,
html,
markdownToHTML,
blogArticle,
layout,
domify,
postTitle,
flickr,
youtube,
undomify,
send
]
app.get("/your/uri", postMiddleware);
简洁?不,干净吗?我认为是这样。灵活?非常。惊人的快?可能不会像我相信的那样快,jsdom是你能做的最重要的事情之一,但我把它作为静态站点生成器使用,所以速度是无关紧要的。当然,在中间件链的开头和结尾添加另一个函数,将最终的HTML写入静态文件,如果它比相应的标记页面正文内容文件更新,则直接为其提供服务,这将是非常简单的。Stackoverflowers,我很想听听关于这种方法的想法和建议 人们说把变量传递给过滤器。我无法理解Peter Lyons的答案,所以我用了这个:
marked = require 'marked'
marked.setOptions
<my options>
app.locals.md = marked
marked=需要“marked”
marked.setOptions
app.locals.md=已标记
然后在翡翠中:
!= md(<markdown string>)
!=md()
又快又脏。可能不太理想,因为它每次运行转换时都没有缓存结果(我认为),但至少它可以工作
(编辑)
您还可以使用“标记”在浏览器中呈现标记,从而从服务器上卸载一些工作并加快加载速度。这非常有趣,谢谢。我其实还没想过要这么做,但这是一种很好的食物
exports.send = function(req, res) {
return res.send(res.html);
};
postMiddleware = [
loadPost,
html,
markdownToHTML,
blogArticle,
layout,
domify,
postTitle,
flickr,
youtube,
undomify,
send
]
app.get("/your/uri", postMiddleware);
marked = require 'marked'
marked.setOptions
<my options>
app.locals.md = marked
!= md(<markdown string>)