pugjs / pug

Pug – robust, elegant, feature rich template engine for Node.js
https://pugjs.org
21.58k stars 1.96k forks source link

`each` should recognize iteration protocol objects #3170

Open strugee opened 4 years ago

strugee commented 4 years ago

Pug Version: 2.0.4

Node Version: 8.10.0

Input JavaScript Values

var pug = require('pug');

var map = new Map([['foo', 'bar']]);

var html = pug.renderFile('input.pug', { some_iterable: map });

console.log(html);

Input Pug

h1 Pug iteration test file
each el in some_iterable
     p= el[0]
     p= el[1]

Expected HTML

<h1>Pug iteration test file</h1><p>foo</p><p>bar</p>

Actual HTML

<h1>Pug iteration test file</h1>

Additional Comments

Here's the relevant MDN documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols

I would be happy to prepare a PR implementing this change but wanted to open an issue first to make sure there aren't any issues I haven't thought of yet. I also think this will be backwards-compatible pretty easily, but don't have the time to double-check at the moment. I'll do that soon.

ForbesLindesay commented 4 years ago

This will require us to adopt some new syntax. I would suggest something like for item of iterable since we already have for as a reserved word, and could easily enough detect the in/of distinction. I'm happy to accept a PR to add this syntax given that node.js supports for of natively.

maxrumsey commented 4 years ago

@strugee Are you currently working on a PR for this? Because if not I'd be happy to take it on.

ForbesLindesay commented 4 years ago

@maxrumsey I've marked it as being worked on. Based on the assumption that one of you or @strugee will be working on it :)

strugee commented 4 years ago

@maxrumsey I am not. If no one lands this I'll probably eventually prepare patches just because I want this in my own projects, but I'm not doing anything right now and would be thrilled if someone else implemented this for me :-)

maxrumsey commented 4 years ago

Yeah I'd be happy to take a stab at this!

maxrumsey commented 4 years ago

@ForbesLindesay Considering the size of Pug, do you have any tips for where I could get started? See the gitter chat.

ForbesLindesay commented 4 years ago

You'll need to start by building an eachOf variant of https://github.com/pugjs/pug/blob/fa8d287ac7155e4e6dd56ff38f4495135659532a/packages/pug-lexer/index.js#L950-L972

You'll then need to handle it in the parser https://github.com/pugjs/pug/blob/fa8d287ac7155e4e6dd56ff38f4495135659532a/packages/pug-parser/index.js#L235-L236

Finally, you'll need to generate js code for it in https://github.com/pugjs/pug/blob/fa8d287ac7155e4e6dd56ff38f4495135659532a/packages/pug-code-gen/index.js#L724

ForbesLindesay commented 4 years ago

To get a local environment setup where all the packages work together, you should use lerna

ForbesLindesay commented 4 years ago

The code to implement this has now been merged, and will be included in the next release.

simonv3 commented 1 year ago

This should probably be added to the docs if it's implemented?

https://pugjs.org/language/iteration.html