Mike Rockétt

Class-based sources added to WeasyPrint for Laravel – version 9 released

This is a major release of the package, introducing some new features and dropping support for old versions. Also, the docs have been moved from the readme to a dedicated site, hosted on Vercel.

#Laravel — 1 May 2024

Since the last post I made about a WeasyPrint for Laravel, a lot has changed. Court Bouillon has released several versions of WeasyPrint, and they’ve managed to squeeze in quite a lot of new functionality, thanks to the community and sponsors.

My Laravel package for WeasyPrint has also been updated to support the latest updates, and carries with it some breaking changes since version 6.

You’re probably better off reading through the changelog to see the full list, but in a nutshell —

  1. Support for class-based sources was added in version 9, released today. 🎉
  2. Some method-signature changes were made in version 9
  3. Configuration started using a DTO-like class, making things a bit more type-safe, in version 8.
  4. The underlying service class changed to being IoC-only, instead of being static.
  5. CLI flags were brought up to speed and made configurable in version 8. Some validation was also added to these to pre-empt the correct input.
  6. As of version 8, the package checks your WeasyPrint version to make sure it’s compatible.
  7. Version 7 only introduced support for newer Laravel and WeasyPrint versions.

From a versioning perspective, the package will tend to stick to the latest (greatest) versions of everything. As at version 9, the package requires at least PHP 8.2 and WasyPrint 61 (62 released recently, however no CLI signatures were made, and so we continue to support it [see notes about this]).

New Docs Site

The readme file was getting a bit long as time went on.

It was once cleaned up, but then got a bit verbose again…

Instead of cleaning up, I decided to reduce potential confusion by creating a dedicated documentation site at weasyprint.rockett.pw with the idea being that concepts are separated out to their own pages, making them easier to follow and digest.

If you notice any issues in the docs, or would otherwise like to contribute to them, please feel free to open a merge request against the documentation repo.

Class-based sources

In the latest release (version 9), support for class-based sources was added, with the idea being that you could forego imperative/procedural calls to the WeasyPrint service and instead use classes to get PDFs rendered. These classes are Responsable, meaning they can be returned directly in a controller without needing to explicitly build and return a PDF as a download or inline attachment.

For example:

namespace App\Documents;
use App\DataTransferObjects\Invoice as InvoiceDTO;
use Illuminate\Contracts\Support\Renderable;
use WeasyPrint\PDF;
final class InvoicePDF extends PDF
public function __construct(
public readonly InvoiceDTO $invoice,
) {}
public function source(): Renderable
return view('invoice', $this->invoice->toArray());
public function filename(): string
return "invoice-{$this->data->id}.pdf";

Then, in a controller/handler:

public function downloadInvoice(Invoice $invoice): InvoicePDF
return new InvoicePDF(/** pass in a data transfer object */);

Something not right?

As always, feel free to open an issue if you encounter any problems.

Previous post: Routisan is Retired