nunjuckseleventyhighlightjs

How do I mark a filter as being safe?


I am trying to set up a syntax highlighting filter for nunjucks using highlight.js. It seems pretty easy to do. In my elevnety.js file I included:

    const hljs = require('highlight.js');
    eleventyConfig.addFilter('highlight', function(txt) {
        return hljs.highlightAuto(txt).value;
    });

It appears that highlight.js is a safe filter and will properly escape it's contents and add markup to control the highlighting, so there is nothing else to do.

In my njk page I try to use this with

{% filter highlight %}
  <xmlstuff>
    <myelements attr1="foo" />
  </xmlsfuff>
{% endfilter %}

The highlighting markup is being generated correctly, but the whole result is being escaped (by nunjucks perhaps) so the resulting page renders all the markup code. Here is what is getting added to the output html page:

  &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;

I know that nunjucks has a safe filter to prevent this from happening, but I don't know how to apply that to say that my filter block doesn't need escaping, and I could not find anything in the documentation. I tried a number of approaches, but they all failed:

{% 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 }}

Is there any way to mark this filter block as safe?


Solution

  • Try to apply env.filters.safe before output.

    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);