Support loop filtering
See original GitHub issueJinja supports pre-filtering an array to be looped over, like so: {% for i in [1, 2, 3] if i > 1 %}
Nunjucks currently doesn’t support this.
It can be emulated by nesting the {% if %}
within the for loop, but this workaround doesn’t interact correctly with {% else %}
blocks on for loops (which I’ve implemented in #259). If you use a non-empty list in a {% for %}
loop, but after applying filtering the list is empty, the {% else %}
clause should be run. Getting this behavior without filtering built into the for loop itself is clunky and verbose.
I’m willing to work up a PR for this, but I’d like to see action on #259 first, since the implementations will interact (and almost certainly conflict if done independently).
Issue Analytics
- State:
- Created 9 years ago
- Reactions:10
- Comments:13
Top Results From Across the Web
Loop Filter - an overview | ScienceDirect Topics
The loop filter of a ΔΣ ADC provides the noise-shaping. In tunable bandpass ΔΣ ADCs, the resonance frequencies of the loop filter are...
Read more >Adaptive Loop Filter - Medium
Adaptive Loop Filter (ALF) is one of in-loop filtering techniques from VVC. The main aim of VVC is to improve compression efficiency of...
Read more >VVC In-Loop Filters | IEEE Journals & Magazine
Adaptive loop filter and cross-component adaptive loop filter are adaptive filters enabling to enhance the reconstructed signal, using for ...
Read more >Filters and Sorting - dotloop support
Filters and sorting are two powerful functions on the My Loops page that allow you to see only the loops you want to...
Read more >Fast Loop Filters - what are they and why are they used?
The sample is taken off from the side of the fast loop filter housing ... For further help or assistance with fast loop...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
To extend @AmeliaBR’s suggestion, I used
bind
to pass additional arguments to the filter function:Remember that the first argument to
bind
is thethis
value, so you need a placeholder value such asnull
:For cases when your array-filtering criteria can’t be defined by a pre-existing boolean attribute on list items,
myList | selectattr(attrName)
won’t work.This is the solution I came to:
To filter a list in Nunjucks, you can use the usual JavaScript
Array.prototype.filter
method. That requires a function that returns boolean (or at least, truthy/falsy) values when it is passed each list item.You need to pass the function, by reference, into the JS
filter
function.But how do you define the
testFunction
?The simplest option is to define a global function in your environment configuration. So this would be the “greater than one” test from the original issue:
In this case, the filtering test is a simple global function, that doesn’t depend on the current template context.
If your test needs data from the context,
Array.prototype.filter
also allows you to define athis
object (which is shared by all list items) as a second parameter. So this compares if thetarget
value on the list items equals thepath
value from the current template context:Alternatively, this is the approach I ended up using. It’s not as clean as the
this
approach, but it’s more flexible, because I don’t need to encapsulate all the relevant context into a single object:I define a test function in my template context as a macro. The macro resolves to an empty string or the literal string ‘false’ if I want the test to fail. (Be careful of extra whitespace here!!!) This macro does the same test as the previous example, if it is defined in the template context with the
path
value:I define the following custom Nunjucks filter function in my configuration environment. It converts the macro result into a boolean that can be used as a JavaScript filter, and uses it to filter a list:
I then filter (in the JavaScript sense) the list, by passing it to my custom filter (in the Nunjucks sense), referring to my custom macro by name as a parameter:
It’s a little messy & difficult to follow, but it gets the job done.
Of course, a nicer built-in way to do any of this would be very helpful.
PS, For anyone else using Metalsmith, you can set custom global functions or filter functions using the
engineOptions
parameter to metalsmith-layouts or metalsmith-in-place. The details for that options object are in the Readme for jstransformers-nunjucks