Project

General

Profile

Feature #853

TemplateLoops should work on functions and multiple variables

Added by Elmer de Looff over 12 years ago. Updated over 12 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Elmer de Looff
Category:
TemplateParser
Target version:
Start date:
2012-06-07
Due date:
% Done:

100%

Estimated time:
Spent time:

Description

TemplateLoops can now only be run on the tag value (including index, but without functions), and they support only a single local variable.

Currently, iterating over the item pairs of a dictionary is done by pushing the dictionary.items() into the template, and then in the for loop, indexing on the single local variable:

import uweb

class PageMaker(uweb.PageMaker):
  def Iterate(self):
    capitals = {'The Netherlands': 'Amsterdam', 'Italy': 'Rome'}
    return self.parser.Parse('capitals.utp', capitals=capitals.items())
<html>
  <body>
    <ul>
      {{ for item in [capitals] }}
      <li>The capital of [item:0] is [item:1]</li>
      {{ endfor }}
    </ul>
  </body>
</html>

Associated revisions

Revision 240:37e48a133956 (diff)
Added by Elmer de Looff over 12 years ago

Added support to TemplateParser for functions parsing in TemplateLoops, as well as tuple unpacking, allowing for clean iteration over dictionaries and nested iterators. This resolves #853.

History

#1 Updated by Elmer de Looff over 12 years ago

  • Status changed from New to Resolved
  • % Done changed from 0 to 70

Applied in changeset 37e48a133956.

#2 Updated by Elmer de Looff over 12 years ago

TemplateParser now supports this mode of iteration, enabling the following practices:

capitals.utp:


<html>
  <body>
    <ul>
      {{ for country, capital in [capitals|items] }}
      <li>The capital of [country] is [capital]</li>
      {{ endfor }}
    </ul>
  </body>
</html>

In the PageMaker:

import uweb

class PageMaker(uweb.PageMaker):
  def _PostInit(self):
    self.parser.RegisterFunction('items': lambda d: d.items())

  def Iterate(self):
    capitals = {'The Netherlands': 'Amsterdam', 'Italy': 'Rome'}
    return self.parser.Parse('capitals.utp', capitals=capitals)

Result:

<html>
  <body>
    <ul>
      <li>The capital of The Netherlands is Amsterdam </li>
      <li>The capital of Italy is Rome</li>
    </ul>
  </body>
</html>

N.B.: We do need to provide the items tag function ourselves, as this is not available by default (yet). It's likely that this will be added in the near future, with behavior as shown.

Also, iterating over nested lists:

citylist.utp:

<html>
  <body>
    <ul>
      {{ for capital, country, inhabitants in [capitals] }}
      <li>The capital of [country] is [capital] and it has [inhabitants] inhabitants</li>
      {{ endfor }}
    </ul>
  </body>
</html>

In the PageMaker:

class PageMaker(uweb.PageMaker):
  def Iterate(self):
    capitals = [('Amsterdam', 'The Netherlands', '790,654'),
                ('Rome', 'Italy', '2,777,979'),
                ('London', 'United Kingdom' , '7,825,200')]
    return self.parser.Parse('capitals.utp', capitals=capitals)

Result:

<html>
  <body>
    <ul>
      <li>The capital of The Netherlands is Amsterdam and it has 790,654 inhabitants</li>
      <li>The capital of Italy is Rome and it has 2,777,979 inhabitants</li>
      <li>The capital of United Kingdom is London and it has 7,825,200 inhabitants</li>
    </ul>
  </body>
</html>

#3 Updated by Elmer de Looff over 12 years ago

  • Assignee changed from Elmer de Looff to Jan Klopper

Jan,

Could you confirm this behavior works for you?

#4 Updated by Jan Klopper over 12 years ago

  • Status changed from Resolved to Closed
  • Assignee changed from Jan Klopper to Elmer de Looff
  • % Done changed from 70 to 100

Yes, this works as expected!

Thanks :)

Also available in: Atom PDF