{pdf}

Sends what its content renders as a PDF instead of the page - a writer in plain PHP, the standard fonts, no library.

Pictures and media Either form

Syntax

{pdf file='name', size='A4', landscape, font='helvetica', title='text'} ... {/pdf}
{pdf preview, file='name'} ... {/pdf}
{pdf download}

Options

file
The file name of the document, default the page's name (.pdf is added).
download
Bare option: sent as an attachment (Content-Disposition: attachment) instead of shown inline.
size
A4 (default), Letter, A5 or Legal.
landscape
Bare option: the page turned.
font
helvetica (default), times or courier - code is always Courier.
title
The document's title, default its first heading.
preview
Bare option: the page stays a page - the content on a sheet with links to open or download it; the same page asked with &padPdf (padPdf=download for the attachment) answers the PDF.

Description

{pdf} turns HTML into a PDF on the server with a writer in plain PHP (tags/_lib/pdf.php): PDF 1.4, the standard fonts every reader has, no library and no headless browser. A pair renders its content as ever - fields, loops, tags - and the response becomes the PDF of it (application/pdf, with the file name) instead of the page; the page cache and tidy are left out. Written as a single tag, {pdf download}, the whole page is the document. Several {pdf} pairs on one page make one document, the first one's options counting.

What is read

h1-h6, p, b/strong, i/em, u, code, a (a link of the document for an http, https or mailto address), br, ul/ol/li (nested), blockquote, pre, hr, tables with colspan and align - the header row repeated on every page - and img: a JPEG of www/<application>/ or a data: address. Another picture is its alt text, any other element its text, and script, style, svg and form fields are left out. The text is WinAnsi (a ? for what it lacks) and is measured with the real font widths, so lines wrap where a reader draws them; past one page there is "2 / 5" at the foot. The document carries no date, so the same page is the same bytes.

Preview and nesting

With preview the page stays a page: the content is shown on a sheet with links "Open name.pdf" and "Download", and the same address with &padPdf answers the document. Only the page the request asked for answers a PDF: a {pdf} inside a page included by {page} shows its content on its sheet, and the response stays the including page's.

An unknown size or font is an error under the strict check. From PHP, padPdf ( $html, [ 'size' => 'Letter' ] ) answers the bytes - for a mail attachment, say.

Examples

An invoice as PDF

The rendered content becomes the response: an A4 document named invoice-2026-114.pdf.

Templateexamples/pdf/1-invoice.src
{pdf file='invoice-{$number}', title='Invoice {$number}'}
  <h1>Invoice {$number}</h1>
  <p>To: <b>{$customer}</b></p>
  <table>
    <tr><th>Item</th><th align="right">Amount</th></tr>
    {lines}<tr><td>{$item}</td><td align="right">{$amount}</td></tr>{/lines}
  </table>
{/pdf}

A preview on a sheet

preview keeps the page a page - the content on a sheet - and &padPdf on the address answers the document.

Templateexamples/pdf/2-preview.pad
{pdf preview, file='packing-list', size='A5'}
  <h1>Packing list</h1>
  <ul>
    {items}<li>{$qty} x {$item}</li>{/items}
  </ul>
{/pdf}
PHPexamples/pdf/2-preview.php
<?php

  $items = [
    [ 'item' => 'Mooring rope, 20 m', 'qty' => 4  ],
    [ 'item' => 'Fender, large',      'qty' => 6  ],
    [ 'item' => 'Life jacket',        'qty' => 10 ] ];

?>
Resultopen alone

Packing list

  • 4 x Mooring rope, 20 m
  • 6 x Fender, large
  • 10 x Life jacket

See also

  • {output} Switches how the running request answers - a web page, the console, a file, a download, JSON or CSV.
  • {page} Renders another page of the application - its PHP and its template - in place of the tag.
  • {mail} Renders a template, or its own content, to an e-mail with an HTML and a text part, and sends it.