Features
- FontAwesome Icons
- Adding Fonts
- Formatters
- Headers and Footers
- HTML Debugging
- LATTE Template Engine
- Page Dimensions
- PDF Viewer
- Preview Features
- Using Stylesheets
- Using Templates
Requirements
PHP>=8.1ProcessWire>=3.0.205RockFrontend>=3.8.2Less- FontAwesome Icons
RockPdf
RockPdf is a wrapper around the mPDF library (https://mpdf.github.io/). While mPDF is a great library it has many parts that are for my taste far too complicated to use.
RockPdf provides helpers to make those tasks easy and fun and also provides several ProcessWire specific shortcuts, for example to save a generated PDF directly to a ProcessWire files field.
Quickstart
First, create the file /site/test.php
:
<h1>Hello World</h1>
Then put this in /site/ready.php
:
/** @var RockPdf $pdf */
$pdf = $modules->get('RockPdf');
$pdf
->load("/site/test.php")
->save(preview: true);
Then reload your page and you'll see your very first generated RockPdf! 😎🚀
Pro-Tip: Enable RockFrontend's LiveReload feature to get live updates of your PDF as soon as you change your markup or stylesheet! 🚀
Pro-Tip 2: As you can see in the screenshot you can use Tracy Debugger to dump variables directly to the screen when working with more complex PDFs! bd()
is your friend 🤩
You can also use variables in that loaded file:
/** @var RockPdf $pdf */
$pdf = $modules->get('RockPdf');
$pdf
->load("/site/test.php", [
// make page 123 available as $page in the document
'page' => $pages->get(123),
'foo' => 'Foo Value',
'date' => date("Y-m-d"),
])
->save(preview: true);
Obviously generating a PDF on every page request does not make much sense for a real world use case. But it's great to show you how quick and easy it is to get startet with RockPdf!
Comparison
You are wondering why not just use mPDF directly? Take a look at this example!
Adding fonts in mPDF:
require_once 'path/to/mpdf/vendor/autoload.php';
$defaultConfig = (new Mpdf\Config\ConfigVariables())->getDefaults();
$fontDirs = $defaultConfig['fontDir'];
$defaultFontConfig = (new Mpdf\Config\FontVariables())->getDefaults();
$fontData = $defaultFontConfig['fontdata'];
$mpdf = new \Mpdf\Mpdf([
'fontDir' => array_merge($fontDirs, [
__DIR__ . '/custom/font/directory',
]),
'fontdata' => $fontData + [ // lowercase letters only in font key
'frutiger' => [
'R' => 'Frutiger-Normal.ttf',
'I' => 'FrutigerObl-Normal.ttf',
]
],
'default_font' => 'frutiger'
]);
// more code to load markup from /site/test.php
// even more code to save and view the PDF
Adding fonts in RockPdf (with live preview):
$modules->get('RockPdf')
->addFont([
'R' => '/site/templates/fonts/Frutiger-Normal.ttf',
'I' => '/site/templates/fonts/FrutigerObl-Normal.ttf',
])
->load("/site/test.php")
->save(preview: true);
Warning
mPDF is an old library and does not support all CSS features you might want to use. For example it will not work with flexbox or grid layouts. But even simpler layouts can break if you nest things in tables, which unfortunately is often the only way to get more complex layouts working in mPDF.
Take this simple example:
<table>
<tr>
<td class='f10'>
<p>Foo</p>
<p>Bar</p>
</td>
</tr>
</table>
The class f10
should set the font size to 10px. But mPDF will not work with this because it does not support nested elements! So you need to add the f10
class to every single <p>
element, which is not very nice. But we have to live with it or write a better PHP-library for creating PDFs. I'm not going to do this...
So instead I'm often using rockfrontend's domtools to add the needed classes. If the paragraphs in the example above came from a TinyMCE field, for example, we could do this:
$dom = rockfrontend()->dom($page->body);
$dom->children()->addClass('f10');
And then output it like this:
<table>
<tr>
<td><?= $body ?></td>
</tr>
</table>
And we'll get the desired result:
<table>
<tr>
<td>
<p class='f10'>Foo</p>
<p class='f10'>Bar</p>
</td>
</tr>
</table>
It's not very nice, but it works...
What's Next
Now let's proceed to some real world examples...