A trick to autonumber in ZPT

I had an interesting issue a few months ago. I was doing some work where I needed to create a pdf from a template. This was a numbered legal document with optional clauses. The problem is this:

How do you make some clauses conditional, but then autonumber the rest?

Normally, you would hardcode clause numbers into the paragraphs, but if you did that, the paragraphs following on the optional ones would be incorrectly numbered.

My coworker came up with the idea of using python’s ‘next’ functionality to just increment an iterator. I was skeptical, since I did not think of a page template as an environment where python objects would be able to keep state outside of tal statements. I was wrong.

The final solution is remarkably simple. In this case, the numbers for the first 20 clauses were hardcoded. We start off with a tal statement to get an iterator:

<body tal:define=”clause_numbers python:iter(range(21,28));”>

This allows you to number up to clause 27.

In each clause, just do the following:

<span tal:content=”python:clause_numbers.next();”></span>

and it works!

In retrospect, this does make sense, since the template is backed by persistent code objects, so an iterator should do the job.