Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding 'each .. of' syntax #3179

Merged
merged 5 commits into from Sep 16, 2019
Merged

Adding 'each .. of' syntax #3179

merged 5 commits into from Sep 16, 2019

Conversation

maxrumsey
Copy link
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>

Copy link
Member

@ForbesLindesay ForbesLindesay left a comment

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.

packages/pug-parser/index.js Outdated Show resolved Hide resolved
packages/pug-lexer/index.js Outdated Show resolved Hide resolved
packages/pug-walk/index.js Outdated Show resolved Hide resolved
+ '// iterate ' + each.obj + '\n'
+ ';(function(){\n'
+ ' var $$obj = ' + each.obj + ';\n'
+ ' if (\'number\' == typeof $$obj.length) {');
Copy link
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
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
Contributor Author

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

each [key, val] of map

Anything else? :)

Copy link
Member

@ForbesLindesay ForbesLindesay left a comment

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.

packages/pug-lexer/index.js Outdated Show resolved Hide resolved
packages/pug-code-gen/index.js Outdated Show resolved Hide resolved
packages/pug-code-gen/index.js Outdated Show resolved Hide resolved
packages/pug-code-gen/index.js Outdated Show resolved Hide resolved
packages/pug-code-gen/index.js Outdated Show resolved Hide resolved
@maxrumsey
Copy link
Contributor Author

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

Copy link
Member

@ForbesLindesay ForbesLindesay left a comment

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.

packages/pug-lexer/index.js Outdated Show resolved Hide resolved
packages/pug-lexer/index.js Outdated Show resolved Hide resolved
packages/pug-parser/index.js Outdated Show resolved Hide resolved
packages/pug-code-gen/index.js Outdated Show resolved Hide resolved
@maxrumsey
Copy link
Contributor Author

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

Copy link
Member

@ForbesLindesay ForbesLindesay left a comment

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
Member

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

@maxrumsey
Copy link
Contributor Author

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

@nmggithub
Copy link

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

Is it available now?

@rollingversions
Copy link

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 14, 2021
@GHolk
Copy link

GHolk commented Jul 4, 2023

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

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.

None yet

4 participants