Skip to content
This repository

Markup hints 

nyeholt edited this page · 9 revisions

Pages 2

Clone this wiki locally

On this page you will find some examples of structuring your pages to format PDF files.

These examples are taken directly from the examples provided in the module - your best bet is to refer to these when putting together your PDF files

See

  • pdfrendition/templates/SamplePageLayout.ss
  • pdfrendition/templates/Includes/PdfFooter.ss
  • pdfrendition/templates/Includes/PdfHeaderFooter.ss
  • pdfrendition/css/pdfrendition.css

Sample Page.ss

Take the following Page.ss layout structure

<div class="printOnly" id="PrintCoverPage">
    <% include PdfFooter %>
    <div class="printLogo">
        <img src="themes/mikenovember/css/images/silverstripe-logo.jpg" />
    </div>

    <h1>$Title</h1>
    <p>Generated $Now.Nice</p>
</div>

<div id="PageContent" class="portrait">
    <% include PdfHeaderFooter %>
    $Content
</div>

<div class="printHidden">
    <div id="PageForm">
    $Form
    </div>
</div>

This defines a few functional areas that you should be aware of. Styling for these can be found in pdfrendition.css

PrintCoverPage

This area defines a block of HTML that is used for the coverpage of the PDF Document. To make sure that it is only displayed in printed copies of the site, the standard CSS file will hide printOnly elements, and the print CSS files (served via media="print") will be used to display these elements.

PdfHeaderFooter and PdfFooter are includes that define elements for the header and footer of the page when used in pdfs.

<div id="PdfHeader">
    <h1>$Title</h1>
</div>
<% include PdfFooter %>
<div id="PdfFooter">
    <p>
        Generated $Now.Nice
    </p>
    <p style="float: right;">
        Page <span id="pagenumber"></span> of <span id="pagecount"></span>
    </p>
</div>

Note how they use the #pagenumber and #pagecount elements - these are filled with page numbers via the following css rules

#pagenumber:before { content: counter(page); }
#pagecount:before { content: counter(pages); }

The headers and footers themselves are inserted into place by the position: running(header); style definitions

#PdfHeader { position: running(header); /* ... */ }
#PdfFooter { position: running(footer); /* ... */ }

which are hooked into the page locations via the overall @page style definition

@page {
    size: A4 portrait;
    margin: 2cm 1cm;

    @top-center {
        content: element(header);
    }

    @bottom-left {
        content: element(footer);
    }
}

Note that both the PrintCoverPage and PageContent elements have headers and footers inserted - this is because they have different @page style definitions for each due to the #PageContent element being assigned as a portrait page.

Some gotchas with page layouts

Why do I get blank pages in my documents?

The Flying Saucer rending engine will create a blank page for any content sitting outside a block element rendered with a particular tag.

Using the example from above, if the last div block didn't have the 'printHidden' class applied to it, the PDF renderer will automatically convert that to a content block (even if there was nothing inside it to display). (As far as I can tell, this following statement may not be 100% accurate...) Because it is of a different @page rendering class (the previous div block is set to the specific @page portrait page style), it is considered to be a new block under the @page style.

Why aren't my footers showing up in my page? Typically, a page would have a structure such as the following

    <div id="PdfHeader">
        <p style="float: right;">
            Page <span id="pagenumber"></span> of <span id="pagecount"></span>
        </p>
        <p>$Title</p>
    </div>
    <div id="PageBody">
        $Content
    </div>

which can be pulled in as a page header using something like

    #PdfHeader { position: running(header); display: block; padding: .5em; border-bottom: 1px solid #000; margin: 0px 5%; }
    @page {
        size: A4;
        margin: 1cm;

        @top-center {
            content: element(header);
        }
    }

In some cases (from experimentation, it seems to be when using page-break-before on div elements), the header won't appear. This is because the header elements need to exist within the context of the 'page' level element, so you need to make sure each block level element that has forced page-break styling has their own definitions for the header located within it somewhere.

Something went wrong with that request. Please try again.