Skip to content

Adding 'each .. of' syntax - #3179

Merged
ForbesLindesay merged 5 commits into
pugjs:masterfrom
maxrumsey:master
Sep 16, 2019
Merged

Adding 'each .. of' syntax#3179
ForbesLindesay merged 5 commits into
pugjs:masterfrom
maxrumsey:master

Conversation

@maxrumsey

Copy link
Copy Markdown
Contributor

This PR adds support for iterating over maps and other iterable objects with the JS syntax each var of map. This example patches issue #3170. The syntax each var of map and for var of map has been introduced, but each and for can be used interchangeably, like with the original each syntax.

All tests run and pass, but I haven't added any tests except for a small fix to recognise the eachOf function is the pug-lexer.

Example Code

JS

var pug = require('pug');

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

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

console.log(html);

Pug

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

Output

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

@ForbesLindesay ForbesLindesay left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a good start. I've made a few comments that I hope are helpful.

Comment thread packages/pug-parser/index.js Outdated
Comment thread packages/pug-lexer/index.js Outdated
Comment thread packages/pug-walk/index.js Outdated
Comment thread packages/pug-code-gen/index.js Outdated
+ '// iterate ' + each.obj + '\n'
+ ';(function(){\n'
+ ' var $$obj = ' + each.obj + ';\n'
+ ' if (\'number\' == typeof $$obj.length) {');

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need to use the for (const ... of ...) { js syntax and not refer to length at all as in general iteration objects are not referenced by indexing. We'll need to decide how/if we want to handle the key. One option would be to assume value, key means de-structure as [value, key]. I think it might be better to offer:

each x of foo

and

each [x, y] of foo

rather than supporting:

each x, y of foo

That way, if we wanted to, we'd have a clear path towards supporting more destructuring in the future.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed it so you can have

each [key, value] of map

as well as

each keyValPair of map

@maxrumsey

Copy link
Copy Markdown
Contributor Author

@ForbesLindesay I've removed all 'else' syntax, and have added the ability to do

each [key, val] of map

Anything else? :)

@ForbesLindesay ForbesLindesay left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking loads closer.

Comment thread packages/pug-lexer/index.js Outdated
Comment thread packages/pug-code-gen/index.js Outdated
Comment thread packages/pug-code-gen/index.js Outdated
Comment thread packages/pug-code-gen/index.js Outdated
Comment thread packages/pug-code-gen/index.js Outdated
@maxrumsey

Copy link
Copy Markdown
Contributor Author

@ForbesLindesay I've updated the parser as well as the code-gen library. Anything else needing a change?

@ForbesLindesay ForbesLindesay left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is probably the last few comments.

Comment thread packages/pug-lexer/index.js Outdated
Comment thread packages/pug-lexer/index.js Outdated
Comment thread packages/pug-parser/index.js Outdated
Comment thread packages/pug-code-gen/index.js Outdated
@maxrumsey

Copy link
Copy Markdown
Contributor Author

@ForbesLindesay That's awesome to hear. Anything else that could be fixed up? :)

@ForbesLindesay ForbesLindesay left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great. Would you mind following up with a couple of tests cases (in a separate PR)?

You can see https://github.com/pugjs/pug/tree/master/packages/pug/test/extends-not-top-level for a test that covers the error handling - i.e. you can test things like each foo, bar] of bing and https://github.com/pugjs/pug/tree/master/packages/pug/test/shadowed-block gives you an example of testing a successful render. It would be good to have tests for Array, Set and Map.

@ForbesLindesay
ForbesLindesay merged commit 8aed002 into pugjs:master Sep 16, 2019
@ForbesLindesay

Copy link
Copy Markdown
Member

This is now merged and will go in the next release.

@maxrumsey

Copy link
Copy Markdown
Contributor Author

That's awesome to hear. Thanks for the help with getting me started. I'll post the PR now.

@nmggithub

Copy link
Copy Markdown

This is now merged and will go in the next release.

Is it available now?

@rollingversions

Copy link
Copy Markdown

pug (2.0.4 → 2.1.0)

New Features

  • Support each ... of ... loops

    each value of iterable
      li= value

    This requires an environment that supports the for (const val of iterable) syntax in JS. You can iterate over Maps, Sets etc. as well as arrays. There is also some destructuring of map keys:

    - const map = new Map([['a', 'x'], ['b', 'y']]);
    each [key, value] of map
      li
        strong= key
        = value

pug-code-gen (2.0.2 → 2.1.0)

New Features

  • Support EachOf nodes

pug-lexer (4.1.0 → 5.0.0)

Breaking Changes

  • Support each ... of ...

    The pug lexer can now output a new token type: eachOf

pug-parser (5.0.1 → 6.0.0)

Breaking Changes

  • Support eachOf tokens and output EachOf nodes

pug-walk (1.1.8 → 1.2.0)

New Features

  • Support EachOf tokens

Packages With No Changes

The following packages have no user facing changes, so won't be released:

  • pug-attrs
  • pug-error
  • pug-filters
  • pug-linker
  • pug-load
  • pug-runtime
  • pug-strip-comments

Edit changelogs

This was referenced Mar 13, 2021
@GHolk

GHolk commented Jul 4, 2023

Copy link
Copy Markdown

Accidentally found this feature. This feature is great, but does not mentioned in pug's iteration docs.

ngsctt pushed a commit to ngsctt/pug that referenced this pull request Feb 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants