Same page multiple times in the same file

Asked by Arnaud on 2013-05-30


I have an ODT model that I fill with python variables in place of the document modifications, then call OpenOffice server to save it as PDF, this works well.

Now I need to achieve something a bit more complex : I have to read an input "cvs-like" text file, each line represents a page in the document. All the pages have the same structure, only the data is different. The number of lines and pages is dynamic. The odf model must have only 1 page that we repeat at will.

a very short example :
my input file :

my odt model :
Dear XX YY

the pdf output file :
page1 :
Dear Mr John ...
Dear Mrs Smith ...

Is it possible to do this, and how ?

If not directly with AppyPod, will I have to generate 1 file per page, then find a tool (if exists) that will concatenate them into 1 odt file, then convert it to pdf ?


Question information

English Edit question
Appy Edit question
No assignee Edit question
Last query:
Last reply:

This question was reopened

Hi Arnaud,
Yes it is possible to do that with pod.
Create an initial page (page de garde). On that page, create a section. Add a note within it to repeat the section:

do section- for people in yourListOfPeople

(Don't know if you are familiar with the "minus" sign, that will prevent the section in itself to be dumped into the result (only the section content will be dumped repeatedly).

In the section, start by inserting a page break. Then, insert the content of your one-page template, as usual.

With this technique, pod will insert repeatedly a page break + your page content. So you will have what you want, excepted that you will get a first blank page. You can do it in reverse order (page content + page break), but in this case the blank page will come at the end.

Another technique is to insert a page break "by code", which allows you to include the page break conditionnaly, excepted after the last page for example.

do text if loop.people.nb < (loop.people.length-1)
from '<text:p text:style-name="podPageBreak"></text:p>'

Don't know if you know object "loop", that gives information about every current loop in pod.
More information about this object in method ForAction.initialiseLoop at

In the next pod version, you will be able to write:

do text if not loop.people.last
from '<text:p text:style-name="podPageBreak"></text:p>'

In ODF, a page break is a paragraph whose style includes the page-break definition. Within every pod result, pod inserts a series of useful default styles. podPageBreak is one of them.

Finally, note also that pod can include external odt documents. For example:
do text for filePath in filePaths
from document(at=filePath, pageBreakBefore=True, pageBreakAfter=False)

For params "pageBreakBefore" and "pageBreakAfter" you will have to wait the next pod version (soon!)

This is also possible to include in a pod result documents in the following formats: PDF, Word, Excel, and HTML documents. When including a PDF file, pod calls Ghostscript (apt-get install Ghostscript) to convert the PDF into a series of PNG files (one per page), and then includes every image into the pod result. When importing a Word or Excel file, pod calls LibreOffice in server mode to convert those docs into PDFs, then calls Ghostscript as explained above.

And in the upcooming pod version it is also possible to call a pod template within another pod template:
do text
from pod(at='/another/pod/template.odt')

With the previous statement, the called pod template will inherit from the pod context of the calling pod template. If you want to specify a specific pod context:

do text
from pod(at='/another/pod/template.odt', context={'another':'context'})


Arnaud (arnaudgeslin) said : #2

Thanks Gaëtan Delannay, that solved my question.

Arnaud (arnaudgeslin) said : #3

Hi Gaëtan

Thanks for your quick answer.
Pod looks incredibly powerful ! I will have to learn more about loops etc.

Many thanks.

Arnaud (arnaudgeslin) said : #4

PS : just a few additional question about your solution : when you write

"do section- for people in yourListOfPeople"

What will be the structure of the python list ? The page template will contain for instance track changes with "forename" and "lastname", when Pod loops on the list of people how will it retrieve the details for the current people ,how do I have to structure my list ?

Hi again,
"yourListOfPeople" can be a list containing structured objects, like dicts:
[ {'forename': 'Geslin', 'lastname': 'Arnaud'}, {'forename': 'Delannay', 'lastname': 'Gaetan'} ]

Then, if your note is
do section- for people in yourListOfPeople

You can write pod expressions like "people['forename']".
Note that instead of writing pod expressions into tracked-changed text, you can also use conditional fields: Insert->Field->conditional, you set "true" as condition, and in the "if" part, you write your pod expression. Using fields instead of track-changed text has one advantage: you can copy/paste text containing fields, and in the copied text, fields are kept. When copy/pasting portions of text containing tracked-changed expressions, it is not possible.

Or you may use objects. If your people are stored in objects (instances of some "Person" or "Client" class), you can then write expressions like "people.forename", and "people.lastname".

In Appy, a convient Object class allows you to build on-the-fly objects, without worrying about creating a static class:

from appy import Object
you = Object(forename="Arnaud", lastname="Geslin")


Arnaud (arnaudgeslin) said : #6

Many thanks again, Appy is great

Arnaud (arnaudgeslin) said : #7

Hi again Gaëtan

The "loop" objet does not seem to be recognized. I tried your code to conditionnaly add a pagebreak and it could not be evaluated.

Thus I simply added a change-track into my section with value "loop.people.nb" and I get an error : "Error while evaluating expression "". name 'loop' is not defined"

By the way the section istelf is correctly repeated so the loop is ran.

Launchpad Janitor (janitor) said : #8

This question was expired because it remained in the 'Open' state without activity for the last 15 days.

Arnaud (arnaudgeslin) said : #9

Gaëtan told me by private mail that the loop object would be available with the next Pod release very soon. I'm waiting to hear about it ;)

Hi Arnaud,
I have published Appy 0.8.4 last week. Could you test it ?
Kind regards,


im working on one small project, and i'm using appypod to generate documents.
And i have following requirement:
i am iterating through mulitple documents ( for d in documents)
every document could have mulitple pages
requirement is for every document to start on even page.
My idea is to read page number in python expresion and
if page number is even then insert page break
if it is odd page number then insert two page breaks.
BUT i dont know way how to read page number in python expression.
Any suggestions ?

Kind Regards

Can you help with this problem?

Provide an answer of your own, or ask Arnaud for more information if necessary.

To post a message you must log in.