如何将过滤器标记为安全?
How do I mark a filter as being safe?
我正在尝试使用 highlight.js 为 nunjucks 设置语法高亮过滤器。这似乎很容易做到。在我的 elevnety.js 文件中,我包含:
const hljs = require('highlight.js');
eleventyConfig.addFilter('highlight', function(txt) {
return hljs.highlightAuto(txt).value;
});
看来 highlight.js 是一个安全的过滤器,会正确地转义它的内容并添加标记来控制突出显示,所以没有其他事情可做。
在我的 njk 页面中,我尝试将其与
一起使用
{% filter highlight %}
<xmlstuff>
<myelements attr1="foo" />
</xmlsfuff>
{% endfilter %}
高亮标记生成正确,但整个结果被转义(可能由 nunjucks 转义),因此生成的页面呈现所有标记代码。这是添加到输出 html 页面的内容:
<span class="hljs-tag">&lt;<span class="hljs-name">xmlstuff</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">myelements</span> <span class="hljs-attr">attr1</span>=<span class="hljs-string">"foo"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">xmlsfuff</span>&gt;</span>
我知道 nunjucks 有一个安全过滤器来防止这种情况发生,但我不知道如何应用它来说明我的过滤器块不需要转义,而且我在文档中找不到任何内容.我尝试了很多方法,但都失败了:
{% filter highlight | safe %}
<xmlstuff>
<myelements attr1="foo" />
</xmlsfuff>
{% endfilter %}
{% filter highlight %}
<xmlstuff>
<myelements attr1="foo" />
</xmlsfuff>
{% endfilter | safe %}
{{ {% filter highlight %}
<xmlstuff>
<myelements attr1="foo" />
</xmlsfuff>
{% endfilter %} | safe }}
有什么方法可以将这个过滤块标记为安全的吗?
尝试在输出前应用env.filters.safe
。
var nunjucks = require('nunjucks');
var env = nunjucks.configure();
env.addFilter('safeFilter', str => env.filters.safe(str));
env.addFilter('unsafeFilter', str => str);
var html = env.renderString(
`{{ str | safeFilter }}\n{{ str | unsafeFilter }}`,
{str: '<h1>Hello</h1>'}
);
console.log(html);
@aikon-mogwai 发布了正确答案。但是对于 eleventy,还需要更多一些,因为需要在 eleventy.js 文件中设置过滤器,并且我们需要访问 nunjucks 环境。我会在这里为后代添加我的完整解决方案。
我看好像 eleventy 没有提供对 nunjucks 环境的访问权限,所以我们需要创建一个并设置它来覆盖现有环境。之后他说的很好:
module.exports = function(eleventyConfig) {
eleventyConfig.addPassthroughCopy('src/images')
/*
* Create and register a Nunjucks environment, just so we
* can get access to the safe filter.
*/
let Nunjucks = require("nunjucks");
let nunjucksEnvironment = new Nunjucks.Environment(
new Nunjucks.FileSystemLoader("src/_includes"), { }
);
eleventyConfig.setLibrary("njk", nunjucksEnvironment);
/*
* Set up a syntax highlighting filter for code blocks
*/
const hljs = require('highlight.js');
eleventyConfig.addNunjucksFilter('highlight', function(txt, lang) {
var txt2;
if (lang == undefined)
txt2 = hljs.highlightAuto(txt).value;
else
txt2 = hljs.highlight(lang, txt).value;
return nunjucksEnvironment.filters.safe(txt2);
});
return {
dir: { input: 'src', output: 'dist', data: '_data' },
passthroughFileCopy: true,
templateFormats: ['njk', 'md', 'css', 'html', 'yml'],
htmlTemplateEngine: 'njk'
}
}
我用 Eleventy@1.0.0-beta.8
实现了这个:
eleventyConfig.addNunjucksFilter('doThing', function (value) {
return this.env.filters.safe(doThing(value));
})
我正在尝试使用 highlight.js 为 nunjucks 设置语法高亮过滤器。这似乎很容易做到。在我的 elevnety.js 文件中,我包含:
const hljs = require('highlight.js');
eleventyConfig.addFilter('highlight', function(txt) {
return hljs.highlightAuto(txt).value;
});
看来 highlight.js 是一个安全的过滤器,会正确地转义它的内容并添加标记来控制突出显示,所以没有其他事情可做。
在我的 njk 页面中,我尝试将其与
一起使用{% filter highlight %}
<xmlstuff>
<myelements attr1="foo" />
</xmlsfuff>
{% endfilter %}
高亮标记生成正确,但整个结果被转义(可能由 nunjucks 转义),因此生成的页面呈现所有标记代码。这是添加到输出 html 页面的内容:
<span class="hljs-tag">&lt;<span class="hljs-name">xmlstuff</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">myelements</span> <span class="hljs-attr">attr1</span>=<span class="hljs-string">"foo"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">xmlsfuff</span>&gt;</span>
我知道 nunjucks 有一个安全过滤器来防止这种情况发生,但我不知道如何应用它来说明我的过滤器块不需要转义,而且我在文档中找不到任何内容.我尝试了很多方法,但都失败了:
{% filter highlight | safe %}
<xmlstuff>
<myelements attr1="foo" />
</xmlsfuff>
{% endfilter %}
{% filter highlight %}
<xmlstuff>
<myelements attr1="foo" />
</xmlsfuff>
{% endfilter | safe %}
{{ {% filter highlight %}
<xmlstuff>
<myelements attr1="foo" />
</xmlsfuff>
{% endfilter %} | safe }}
有什么方法可以将这个过滤块标记为安全的吗?
尝试在输出前应用env.filters.safe
。
var nunjucks = require('nunjucks');
var env = nunjucks.configure();
env.addFilter('safeFilter', str => env.filters.safe(str));
env.addFilter('unsafeFilter', str => str);
var html = env.renderString(
`{{ str | safeFilter }}\n{{ str | unsafeFilter }}`,
{str: '<h1>Hello</h1>'}
);
console.log(html);
@aikon-mogwai 发布了正确答案。但是对于 eleventy,还需要更多一些,因为需要在 eleventy.js 文件中设置过滤器,并且我们需要访问 nunjucks 环境。我会在这里为后代添加我的完整解决方案。
我看好像 eleventy 没有提供对 nunjucks 环境的访问权限,所以我们需要创建一个并设置它来覆盖现有环境。之后他说的很好:
module.exports = function(eleventyConfig) {
eleventyConfig.addPassthroughCopy('src/images')
/*
* Create and register a Nunjucks environment, just so we
* can get access to the safe filter.
*/
let Nunjucks = require("nunjucks");
let nunjucksEnvironment = new Nunjucks.Environment(
new Nunjucks.FileSystemLoader("src/_includes"), { }
);
eleventyConfig.setLibrary("njk", nunjucksEnvironment);
/*
* Set up a syntax highlighting filter for code blocks
*/
const hljs = require('highlight.js');
eleventyConfig.addNunjucksFilter('highlight', function(txt, lang) {
var txt2;
if (lang == undefined)
txt2 = hljs.highlightAuto(txt).value;
else
txt2 = hljs.highlight(lang, txt).value;
return nunjucksEnvironment.filters.safe(txt2);
});
return {
dir: { input: 'src', output: 'dist', data: '_data' },
passthroughFileCopy: true,
templateFormats: ['njk', 'md', 'css', 'html', 'yml'],
htmlTemplateEngine: 'njk'
}
}
我用 Eleventy@1.0.0-beta.8
实现了这个:
eleventyConfig.addNunjucksFilter('doThing', function (value) {
return this.env.filters.safe(doThing(value));
})