Skip to content

Chapter 6: More about pages and page structures

More about template and pageTemplate

We have already seen that the <template> has to appear at the start of an RML document (after the prolog). This section sets out to explain it more fully.

A <template> is the section where the layout of a document is set out - both for the whole document and for individual pages within it.

Up to now, we have just been using <template> without any options. But the <template> tag has a number of optional attributes that you can use to set settings for the whole document:

pageSize sets the size of the page. This takes a pair of numbers for the width and the height of the page. If you don't give it any numbers, it defaults to A4 (the international standard page size which differs from the American standard page size of letter, but is a standard in other places such as the UK). While this is a sensible default, it's usually best to explicitly specify a size. Common sizes are (21cm, 29.7cm) or (595, 842) for A4, (8.5in, 11in) for letter, and (8.5in, 17in) for legal. rotation sets the angular orientation of the page. This is a float or integer number that should be a multiple of 90. The default value is zero.

leftMargin and rightMargin set the horizontal margins for the page. topMargin and bottomMargin set the vertical margins for the page.

You can also set the title of the document with the title attribute (which defaults to '(untitled)') and the author with the author attribute (which defaults to '(unauthored)').

There are also the optional showBoundary and allowSplitting attributes, which can both be set to "0" or "1" (or "true" and "false"). The showBoundary attribute is off by default, but when it is set to true, it shows a black border around any frames on the page.

<template> allows you to set options for the whole document. The <pageTemplate> tag allows you to set options for individual pages. You can have more than one <pageTemplate> inside the template section. This allows you to have different pageTemplates for each page that requires a different structure. For example, the title page of a report could have a number of graphics on it while the rest of the pages are more text-orientated.

Each <pageTemplate> tag must have the mandatory attribute id. This gives the template a name, and allows both rml2pdf and you to refer to it by name. The <pageTemplate> tag also allows you to override the rotation and pageSize set by the <template> tag. As well as these attributes, you can put any number of <pageGraphics> into a <pageTemplate> (<pageGraphics> are the containers for the <drawString> and shape-drawing commands we saw earlier).

In practice, you may have two <pageGraphics> sections inside a <pageTemplate>. The way this is interperted by RML2PDF is that the first one is carried out before the contents of the story for that page, and the second one is carried out after the story. This may be of use when you need some elements to overlap others, and particularly useful when you are using the <includePdfPages> tag. IncludePdfPages places a number of pages imported from another PDF file into your document, placing them over the content you already have (including any header and footers you have designed). This may mean it obscures headers, footers or something else you need on very page. The way around this is to place your headers and footers in a second pageGraphics section, which ensures that it will appear over anything in your story. Provided you have sensibly defined frames it won't appear over the main content of your page, but it will appear over the top of your included PDFs allowing you to have the same look-and-feel for these pages as you do for the rest of your document.

(See section 8.8 ("Integrating with PageCatcher: catchForms, doForm and includePdfPages") for more info on the <includePdfPages> tag.)

Frame and nextFrame

As well as containing <pageGraphics>, each <pageTemplate> can also contain frames. These frames can split the page into more than one region. For each frame in a <pageTemplate>, you must supply an id, the X and Y co-ordinates of the bottom left hand corner, as well as the width and height of the frame. You can have one frame in a page, or use two or more to split it into a multi-column layout. Frames really come into their own when you use paragraphs and flowables (see the section on "Advanced text" below).

This is how it looks in practice:

<frame id="main" x1="4in" y1="2in" width="3in" height="7in"/>

(When you are using text in <para></para> tags, you can use the <nextFrame/> tag to force it into the next frame on the page. Look at the section on "Advanced text" later in this document for more details on this). An additional attribute overlapAttachedSpace can be set to 0 or 1 to force the frame to overlap space that is implicitly attached to flowables by their styles. See section 6.5 on styles. The default value for this attribute is set using the site wide configuration for reportlab (in reportlab/rl_config.py).

condPageBreak: conditional page breaks

The <condPageBreak/> is a "CONDitional Page Break". To use it, you give it a height in any units that RML can handle. It then compares this height with the remaining available space on a page. If the space is sufficient, then the next elements are placed on the current page, but if there is less space than the height you have given it anything following the <condPageBreak/> tag is continued on the next page.

That is what happens on pages with only one frame. On pages that have multiple frames, this tag acts as a conditional frame break. If the space in the current frame isn't enough, it will break and place what follows in the next frame rather than on the next page. The tag and its syntax still remain the same.

This tag is particularly useful with large tables, where you want the whole table to be presented on one page rather than split between two. It can also be used where you have a collection of images, and you want them all to be on the same page.

<condPageBreak/> has only one attribute - the mandatory one of height. Examples:

<condPageBreak height="1in"/>
<condPageBreak height="72"/>

storyPlace: out of band flowables

The <storyPlace> container is a "flowable story that's placed". This allows for dynamically specified frames to be constructed in the story. This tag is like having an <illustration> & <place> combination although you cannot separate an illustration from its frame as you can with <storyPlace>.

<storyPlace> takes 4 required attributes and one optional one. x, and y are the x and y co-ordinates for where you want the flowables placed. width and height are the width and height of the flowable. Finally the origin can be one of page|frame|local. If not specified local is assumed. The origin attribute specifies where the x and y attributes are based.

Examples:

<storyPlace x="0" y="0" width="18cm" height="1cm" origin="page">
    <para>This is right at the bottom of the page</para>
</storyPlace>
<storyPlace x="0" y="0" width="18cm" height="1cm" origin="frame">
    <para>This is right at the bottom of the current frame</para>
</storyPlace>
<storyPlace x="0" y="0" width="18cm" height="1cm" origin="local">
    <para>This is right at the current frame position!</para>
</storyPlace>

pto: Please Turn Over Control

The <pto> tag is a flowable container that holds an arbitrary number of other flowables. The first two may be special <pto_trailer> or <pto_header> tags each of which may contain arbitrary flowables. The idea is that the trailer flowables are issued at the bottom of the page whenever the main container flowables split; the header flowables appear at the top of the next frame.

<pto>
    <pto_trailer>
        <para textColor="blue" style="pto">
            See you on next frame
        </para>
    </pto_trailer>
    <pto_header>
        <para textColor="blue" style="pto">
            back from the previous frame
        </para>
    </pto_header>
    <para style="h1">A header</para>
    <para style="bt">
        Many vast star fields in the plane of our Milky Way Galaxy
        are rich in clouds of dust, and gas. First and foremost,
        visible in the above picture are millions of stars, many
        of which are similar to our Sun. Next huge filaments of
        dark interstellar dust run across the image and block the
        light from millions of more stars yet further across our Galaxy.
    </para>
</pto>

keepInFrame fixed space control

The <keepInFrame> tag is a flowable container that holds an arbitrary number of other flowables. The intention is that the container controls the space allocated to the inner flowables. Errors will be caused by attempts to use <nextFrame/> and similar tags inside the <keepInFrame> container.

The <keepInFrame> tag takes several attributes. maxWidth is the maximum width. If zero then the available width will be used. maxHeight is the maximum height. If zero then the available height will be used. frame if specified this should be the name or index of the frame in which the contents should be drawn. The framechange takse place before widths etc are evaluated. mergeSpace if {{ code }}1{{ endcode }} then adjacent pre and post space for the content elements will be merged. onOverflow this specifies the action to be taken if the contents is too large.

Allowed values are {{code}}error{{endcode}} ie raise an error, {{code}}overflow{{endcode}} just scrawl all over the page, {{code}}shrink{{endcode}} shrink the contents to fit the allowed space, & {{code}}overflow{{endcode}} truncate the contents at the borders of the allowed space.

The example below shows how to cram star fields into a one inch square.

<keepInFrame maxWidth="72" maxHeight="72">
    <para style="h1">A header</para>
    <para style="bt">
        Many vast star fields in the plane of our Milky Way Galaxy
        are rich in clouds of dust, and gas. First and foremost,
        visible in the above picture are millions of stars, many
        of which are similar to our Sun. Next huge filaments of
        dark interstellar dust run across the image and block the
        light from millions of more stars yet further across our Galaxy.
    </para>
</keepInFrame>

imageAndFlowables tag

The <imageAndFlowables> tag allows flowables to flow around an image. Errors will be caused by attempts to use <nextFrame/> and similar tags inside the <imageAndFlowables> container.

The <imageAndFlowables> tag takes several attributes. imageName the name of the image file or path. imageWidth the width of the image; using 0 will cause the pixel size in points to be used. imageHeight the height of the image; using 0 will cause the pixel size in points to be used. imageMask a transparency colour or the word "auto"; this only works for image types that support transparency. imageLeftPadding space to be used on the left of the image. imageRightPadding space to be used on the right of the image. imageTopPadding space to be used on the top of the image. imageBottomPadding space to be used on the bottom of the image. imageSide which side the image should go on; "left" or "right".

Example:

<imageAndFlowables imageName="../doc/images/replogo.gif"
                   imageWidth="141" imageHeight="90" imageSide="left">
    <para style="h1">Test imageAndFlowables tag with paras</para>
    <para style="style1">
        We should have an image on the <b>right</b>
        side of the paragraphs here.
    </para>
    <para style="style1">
        Summarizing, then, we assume that the fundamental error of regarding
        functional notions as categorial may remedy and, at the same time,
        eliminate the levels of acceptability from fairly high (e.g. (99a)) to
        virtual gibberish (e.g. (98d)).  This suggests that the theory of
        syntactic features developed earlier delimits a descriptive fact.  We
        have already seen that any associated supporting element is not quite
        equivalent to the traditional practice of grammarians.  From C1, it
        follows that the theory of syntactic features developed earlier can be
        defined in such a way as to impose irrelevant intervening contexts in
        selectional rules.  So far, a descriptively adequate grammar is rather
        different from a general convention regarding the forms of the grammar.
    </para>
</imageAndFlowables>

More about stylesheets

Just like in a word processor, RML allows you to define a stylesheet at the start of your document, and then apply it to paragraphs later on. This means that you can define a complicated mixture of settings that you want to apply to paragraphs, only define it in one place, and refer to it with a simple name at the start of each paragraph rather than having to type or cut-and-paste large blocks of text over and over for each paragraph.

Each stylesheet starts with the <stylesheet> tag. There may then be an optional initialisation section where aliases can be set (bounded by the pair of tags <initialize></initialize>). After that come a number of <paraStyle> tags - each one defining a style that you want to use for paragraphs. The <paraStyle> tag must have an attribute name, and then may have as many optional attributes as you want, each one setting one feature of the appearance of a paragraph.

Each one of these <paraStyle> tags is an empty element (i.e. it is closed with a "/>" rather than a separate closing tag), but you might want to indent the tag so that each of the options is on a separate line. This makes it easier to see what each style is defining (see the example below for how this looks).

One attribute for <paraStyle> that isn't the same as those used by <para> is the parent attribute. Once you have defined a style using a <paraStyle> tag, you can use those settings as a basis for other styles. parent allows one style to inherit from another.

The other attribute that isn't shared by the <para> tag is backColor. As you can probably guess, this attribute sets a background color for the paragraph it is describing.

The following optional attributes for <paraStyle> are the same as those for the <para> tag - you can find more description of them in the "Advanced text" section below: fontName, fontSize, leading, leftIndent, rightIndent, firstLineIndent, alignment, spaceBefore, spaceAfter, bulletFontName, bulletFontSize, bulletIndent, textColor.

Here is an example of how the <stylesheet> tag might look in use:

<stylesheet>
    <initialize>
        <alias id="style.normal" value="style.Normal"/>
    </initialize>

    <paraStyle name="h1"
               fontName="Courier-Bold"
               fontSize="12"
               spaceBefore="0.5 cm"
               />

    <paraStyle name="style1"
               fontName="Courier"
               fontSize="10"
               />

    <paraStyle name="style2"
               parent="style1"
               leftIndent="1in"
               />

    <paraStyle name="style7"
               parent="style1"
               leading="15"
               leftIndent="1in"
               rightIndent="1in"
               />
</stylesheet>

stylesheets also allow you to define styles for other tags - you can define styles for blockTables with the <blockTableStyle> tag, or the various form creation elements (checkBoxes, letterBoxes and textBoxes) with the boxStyle tag. Refer to the sections on blockTables and Form Field Tags later in this document for details on how to use these.