- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
尊敬的黑客,
我希望在 Jade 模板中过滤一个充满 Markdown 的字符串。我在变量中有 Markdown。
Jade 在 Markdown 中插入一个变量就好了:
这个:
var jade = require('jade');
var jade_string = [
':markdown',
' ## This is markdown!',
' * First',
' * #{var2}',
' * Third'
].join('\n');
var fn = jade.compile( jade_string, { pretty: true } );
console.log( fn( { var1: "First!", var2: "Second!" } ) );
产生这个:
<h2>This is markdown!</h2>
<ul>
<li>First</li>
<li>Second!</li>
<li>Third</li>
</ul>
但是,我所拥有的是变量内部的实际完整 Markdown。还有这个:
var jade = require('jade');
var jade_string = [
'div.markedup',
' :markdown',
' \\#{var2}'
].join('\n');
var fn = jade.compile( jade_string, { pretty: true } );
var markdown = [
'## I am marked!',
'* One',
'* Two'
].join('\n');
console.log( fn( { var1: "First!", var2: markdown } ) );
只提供这个:
<div class="markedup"><p>## I am marked!
* One
* Two</p>
</div>
因此在我看来,Jade 会在 执行任何变量之前过滤 block 插值,然后在生成的 HTML 中插入变量。这是如果你想用 Markdown 编写你的模板,那很好,但这并不多如果您想在 Markdown 中编写您的内容,请提供帮助。
我知道我可以通过更多编程来解决这个问题,但我觉得我一定是少了什么。毕竟,将 Markdown 内容的片段保存在一个数据库并将生成的 HTML 片段填充到模板中似乎:markdown
过滤器最明显的用例。
在 Jade 中是否有一种“正常”的方式来做到这一点?
非常感谢您的启发。
最佳答案
我认为答案是更多的编程,但我会向您展示我所做的。我使用自定义中间件,让我在获得最终 HTML 文档输出之前组合任意转换过程。因此,例如,我的 middleware.js 模块中有以下过滤器,我将依次解释。
如此简单的 View 只使用普通的 jade 及其用于 markdown、javascript、coffeescript 的各种过滤器。某些 View (例如博客文章)需要更复杂的中间件链,如下所示。
首先,根据请求,我建立了包含此响应核心内容的文件,并将其设置为 res.viewPath
上的属性。 .这可以是原始 HTML 片段文件或 Markdown 文件。然后我通过一系列中间件转换发送响应。我用 res.html
和 res.dom
在建立响应时存储响应的中间表示。
这个只存储原始 HTML(只是一个没有头部或布局的文档主体片段)。
html = function(req, res, next) {
if (!/\.html$/.test(res.viewPath)) return next();
return fs.readFile(res.viewPath, "utf8", function(error, htmlText) {
res.html = htmlText;
return next(error);
});
};
这会将 markdown 文件转换为 HTML(使用 markdown-js 模块)。
markdownToHTML = function(req, res, next) {
if (!/\.md$/.test(res.viewPath)) return next();
return fs.readFile(res.viewPath, "utf8", function(error, markdownText) {
res.html = markdown(markdownText);
return next(error);
});
};
我有一个子布局,它位于我的主布局内,但围绕着每篇博文。所以我将博客文章包装在此处的子布局中。 (未显示的单独代码从 json 元数据文件生成 res.post
对象)。
blogArticle = function(req, res, next) {
var footerPath, post;
post = res.post;
footerPath = path.join(__dirname, "..", "templates", "blog_layout.jade");
return fs.readFile(footerPath, "utf8", function(error, jadeText) {
var footerFunc;
if (error) return next(error);
footerFunc = jade.compile(jadeText);
res.html = footerFunc({
post: post,
body: res.html
});
return next();
});
};
现在我将布局围绕主要内容 HTML 进行包装。请注意,我可以在此处设置诸如页面标题之类的内容,或者等到稍后,因为我可以在此之后通过 jsdom 操作响应。我做body: res.html || ""
所以我可以渲染一个空布局,如果方便的话,稍后再插入正文。
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
下面的函数只允许我在没有额外的 <script>
的情况下取回 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);
});
};
这是我进行的自定义转换。这可以替换像 <flickrshow href="http://flickr.com/example"/>
这样的虚构 DSL 标签使用真正有效的 HTML,否则会很讨厌 <object>
我将不得不在每篇博客文章中复制样板文件,如果 flickr 曾经更改过他们使用的样板文件标记,那么在许多单独的博客文章 Markdown 文件中修复它将会是一种维护上的痛苦。他们目前使用的样板文件在 flickrshowTemplate
中。变量并包含一个 mustache 占位符 {URLs}
.
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 视频也是如此。 <youtube href="http://youtube.com/example"/>
.
exports.youtube = function(req, res, next) {
var $ = res.dom.window.$;
$("youtube").each(function(index, elem) {
var $elem, URL;
$elem = $(elem);
URL = $elem.attr("href");
return $elem.replaceWith(youtubeTemplate.replace(/\{URL\}/, URL));
});
return next();
};
现在我可以根据需要更改标题,添加/删除 javascript 或样式表等。这里我在布局已经呈现后设置标题。
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 写入一个静态文件,如果它比对应的 markdown 页面主体内容文件更新,则直接提供服务。 Stackoverflowers,我很想听听关于这种方法的想法和建议!
关于node.js - 在 Jade/Node.js 中过滤 Markdown 内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9159826/
我正在为我的按钮使用 onClick 功能。我的按钮代码如下所示: Button 1 Button 2 我的 JS 函数如下所示: function fadeNext(selectedId, spee
首先,我想提一下,我理解每个人在不提供至少一些试验或错误的情况下提出问题的感受,但这纯粹是一种知识需求,话虽如此,我会去提前问。 我一直无法弄清楚如何将保存在 MySQL 表中的 600-1000 个
我想做的事情有点令人困惑,而且我英语不太好,所以我先把代码贴在这里,这样你就可以很容易地理解: 以下是表单内容: Testing for Stackoverflow Option1
我学习 SDL 二维编程已有一段时间了,现在我想创建一个结合使用 SDL 和 OpenGL 的程序。我是这样设置的: SDL_Init(SDL_INIT_VIDEO); window = SDL_Cr
我创建了 2 个 data-* 标签。数据类别和数据标签。单击 href 标签后,我想复制该数据类别和数据标签以形成输入。我的代码是:
我想用 CSS 换行。我正在使用内容。 td:before { content: "Test\A Test2"; } 它不工作。如何正确
这个问题已经有答案了: Java Class that implements Map and keeps insertion order? (8 个回答) 已关闭 6 年前。 我有一个 HashMap
我正在尝试使用 JMeter 执行端到端测试。测试涉及写入SFTP文件夹并从另一个SFTP文件夹读取写入操作生成的文件。 我能够使用 JMeter SSH SFTP 插件连接到 SFTP 文件夹,并能
您好,我有带有标准服务器端 Servlet 的 GWT 客户端。 我可以从 GWT 客户端上传文件并在服务器端读取其内容 我可以将其作为字符串发送回客户端 但是 我有 GWT FormPanel与操作
我在 Plone 4.3.9 中创建了一个自定义类型的灵巧性,称为 PersonalPage,必须只允许在特定文件夹中使用 成员文件夹/用户文件夹 . 在他的 FTI 中,默认情况下 False .
在新(更新)版本的应用程序中更改小部件布局的最佳做法是什么?当新版本提供更新、更好的小部件时,如何处理现有小部件? 最佳答案 我认为您必须向用户显示一个弹出窗口,说明“此版本中的新功能”并要求他们重新
在我的应用程序中,我使用支持 View 寻呼机和 PagerTabStrip。进入查看寻呼机我有一些 fragment ,进入其中一个我正在使用支持卡片 View 。运行应用程序后,所有卡片 View
我有以下布局文件。基本上我有谷歌地图,在左上角我有一个 TextView,我需要在其中每 15 秒保持一次计数器以刷新 map 。布局很好。
我使用如下结构: HashMap > > OverallMap 如果我这样做: OverallMap . clear ( ) clear() 丢弃的所有内容(HashMap 对象、Integer 对
我在数据库中有 1000 张图像。在页面加载时,我随机显示 60 张图片,当用户滚动时,我通过 AJAX 请求添加 20 张图片。 第一种方法 我所做的是将所有图像加载到一个容器中,然后隐藏所有图像并
我正在使用 woocommerce 创建一个网上商店。 我想在每个产品上添加一个包含产品信息的表格,例如颜色、交货时间等等。 但是当我添加这张表时。本产品消失后的所有内容。 我的表的代码: td {
This question already has an answer here: What does an empty value for the CSS property content do?
因此,我正在与我的 friend 一起为 Google Chrome 开发一个扩展程序,对于大多数功能(即日历、设置等),我们打开一个模式,这样我们就不必重定向到另一个页面。当您在内容之外单击时,我们
我将可变高度的 CSS 框设置为在更大的 div 中向左浮动。现在我想添加一个标题,其中文本在框的左侧垂直显示(旋转 90 度),如下面的链接所示(抱歉还不能发布图片)。 http://imagesh
相关页面位于 www.codykrauskopf.com/circus 如果您查看我页面的右侧,在半透明容器和浏览器窗口边缘之间有一个间隙。我看了看,出于某种原因,wrap、main、content
我是一名优秀的程序员,十分优秀!