Repository: mozilla/nunjucks (js)

Issue:
Add forceescape filter
Seems that escaping of `caller()` no longer works with switched off default auto escaping and returns raw html.

I'm not sure is it intentional, or is it a bug.

``` jinja
{% macro example() %}
<pre><code>{{ caller()|escape }}</code></pre>
{% endmacro %}

{% call example() %}
First line <br> second line
{% endcall %}
```

should return

``` html
First line &lt;br&gt; second line
```

but returns

``` html
First line
second line
```


Pull request description:
Add "forceescape" filter
## Summary

Proposed change:

Adds the [`forceescape` filter](http://jinja.pocoo.org/docs/2.10/templates/#forceescape). 

Closes #782.


## Checklist

I've completed the checklist below to ensure I didn't forget anything. This makes reviewing this PR as easy as possible for the maintainers. And it gets this change released as soon as possible.

* [x] Proposed change helps towards [*purpose of this project*](https://github.com/mozilla/nunjucks/blob/master/CONTRIBUTING.md#purpose).
* [x] [*Documentation*](https://github.com/mozilla/nunjucks/tree/master/docs/) is added / updated to describe proposed change.
* [x] [*Tests*](https://github.com/mozilla/nunjucks/tree/master/tests) are added / updated to cover proposed change.
* [x] [*Changelog*](https://github.com/mozilla/nunjucks/blob/master/CHANGELOG.md) has an entry for proposed change (if user-facing fix or feature).

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c65d53b..11999e4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
 Changelog
 =========
 
+* Add `forceescape` filter. Fixes [#782](https://github.com/mozilla/nunjucks/issues/782)
 
 3.1.2 (Feb 23 2018)
 -------------------
diff --git a/docs/templating.md b/docs/templating.md
index 85629e3..bdbc212 100644
--- a/docs/templating.md
+++ b/docs/templating.md
@@ -1124,6 +1124,10 @@ This default can be overridden by using the first parameter.
 3.5
 ```
 
+### forceescape
+
+Enforce HTML escaping. This will probably double escape variables.
+
 ### groupby
 
 Group a sequence of objects by a common attribute:
diff --git a/nunjucks/src/filters.js b/nunjucks/src/filters.js
index 5c56900..84bffa0 100644
--- a/nunjucks/src/filters.js
+++ b/nunjucks/src/filters.js
@@ -156,6 +156,13 @@ function first(arr) {
 
 exports.first = first;
 
+function forceescape(str) {
+  str = (str === null || str === undefined) ? '' : str;
+  return r.markSafe(lib.escape(str.toString()));
+}
+
+exports.forceescape = forceescape;
+
 function groupby(arr, attr) {
   return lib.groupBy(arr, attr);
 }


Test patch:
diff --git a/tests/filters.js b/tests/filters.js
index 6e6e848..00e7d3c 100644
--- a/tests/filters.js
+++ b/tests/filters.js
@@ -228,6 +228,12 @@
       equal('{{ "0" | float }}', '0');
     });
 
+    it('forceescape', function(done) {
+      equal('{{ str | forceescape }}', { str: r.markSafe('<html>')}, '&lt;html&gt;');
+      equal('{{ "<html>" | safe | forceescape }}', '&lt;html&gt;');
+      finish(done);
+    });
+
     it('int', function() {
       equal('{{ "3.5" | int }}', '3');
       equal('{{ "0" | int }}', '0');