0

我正在尝试使用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 页面的内容:

  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-name&quot;&gt;xmlstuff&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-name&quot;&gt;myelements&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;attr1&lt;/span&gt;=&lt;span class=&quot;hljs-string&quot;&gt;&quot;foo&quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-name&quot;&gt;xmlsfuff&lt;/span&gt;&amp;gt;&lt;/span&gt;

我知道 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 }}

有没有办法将此过滤器块标记为安全?

4

3 回答 3

1

@aikon-mogwai 发布了正确答案。但是对于 111,需要更多一点,因为需要在 110.js 文件中设置过滤器,并且我们需要访问 nunjucks 环境。我将在此处添加我的完整解决方案以供后代使用。

我看起来不像 110 提供对 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'
  }
}
于 2020-05-19T11:35:58.097 回答
1

尝试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);
于 2020-05-15T23:04:37.797 回答
0

我是这样实现的Eleventy@1.0.0-beta.8

eleventyConfig.addNunjucksFilter('doThing', function (value) {
  return this.env.filters.safe(doThing(value));
})
于 2022-01-14T02:18:15.620 回答