⚡️ MIRROR — A feature-rich Laravel wrapper for the WeasyPrint Document Factory.

Overview

WeasyPrint for Laravel

License Version Downloads Pipeline Status

A feature-rich Laravel wrapper for the WeasyPrint Document Factory.

This package requires Laravel 8.47+ running on PHP 8+ in order to operate. The reason a minor version of Laravel is required is due to the addition of scoped singletons, which adds first-class support for Laravel Octane. In the previous version of this package, the singleton was immutable, which meant that every mutable-by-design method would actually return a cloned instance of the service.

See the Changelog | View the Upgrade Guide



Supported WeasyPrint Versions

There are two versions of the package that are supported. v6 is the latest, and is the only version that will receive new features. v5 is the previous, and will only receive bug-fixes and security-patches. The table below outlines supported versions:

Package WeasyPrint Laravel PHP Branch
^6.0 (current) ≥ v53 (pydyf) 8.47+ (scoped singletons) 8.x 6.x
^5.0 (previous) < v53 (cairo) 8.x (immutable singletons) 8.x 5.x

The guides below are for v6:

Package Installation

First make sure WeasyPrint v53+ is installed on your system.

Then, install the package with Composer:

$ composer require rockett/weasyprint

The package will be discovered and registered automatically.

If you would like to publish the default configuration, you may run the command shown below. It’s not recommended to do this however, as the config file does read your environment variables. It is recommended to publish the config file only when you are changing the names of the variables, or you need to resolve them in another way.

$ php artisan vendor:publish --tag=weasyprint.config

Service Instantiation

WeasyPrint for Laravel provides different mechanisms you can use to get going. You may make use of the service class directly, use dependency injection, or use the Facade.

Option 1. Service Class

use WeasyPrint\Service as WeasyPrintService;

$source = '<p>WeasyPrint rocks!</p>';
$service = WeasyPrintService::new()->prepareSource($source);

This will give you a new WeasyPrint service class instance, ready to render a PDF or PNG based on the source provided to prepareSource (more on this further down).

When using the service class directly, the default configuration will be loaded in for you, unless you pass custom configuration into the new method, which is just a static alias to the constructor:

$service = WeasyPrintService::new(
  binary: '/absolute/path/to/weasyprint',
  timeout: 5000,
);

Configuration options are discussed further down.

If you prefer a short-hand and don’t care much for changing any configuration, you can use the createFromSource static constructor instead:

$service = WeasyPrintService::createFromSource($source);

Option 2. Dependency Injection

use WeasyPrint\Contracts\Factory as WeasyPrintFactory;

class GeneratePDF
{
  public function __invoke(WeasyPrintFactory $factory)
  {
    $source = '<p>WeasyPrint rocks!</p>';
    $service = $factory->prepareSource($source);
  }
}

To use dependency injection, you need to use the Factory contract, which will resolve the WeasyPrint service singleton from the Service Container. This singleton is scoped to ensure support for Laravel Octane.

To reconfigure this instance, you may call mergeConfig on the new service instance:

$service->mergeConfig(
  binary: '/absolute/path/to/weasyprint',
  timeout: 5000,
)

You do not need to call this method at any specific point in time, but you must call it before you build the output.

Option 3. Facade

use WeasyPrint\Facade as WeasyPrint;

$source = '<p>WeasyPrint rocks!</p>';
$service = WeasyPrint::prepareSource($source);

Similar to dependency injection, using the Facade will give you an instance of the WeasyPrint service singleton. The Facade resolves to the Factory contract which, in turn, provides you with the singleton.

To change the configuration, you may call the mergeConfig method, just as you would with dependency injection.

Building the Output

Now that you know how to instantiate a service class instance and prepare the source input, you are ready to build the output. To do this, you can call the build() method, which will return an instance of Objects\Output.

$output = $service->build();

The $output object makes the following methods available:

public function download(string $filename, array $headers = [], bool $inline = false): StreamedResponse;

This method creates a Symfony StreamedResponse that may be used to download the PDF to the client (browser).

public function inline(string $filename, array $headers = []): StreamedResponse;

Likewise, this method does the same, except it uses an inline attachment so that it may be displayed in the browser. This is just a shorthand for download, setting $inline to true.

public function putFile(string $path, ?string $disk = null, array $options = []): bool;

This method forwards the data to Laravel’s Filesystem using the Storage facade’s put method, which gives you the ability to save the PDF to disk.

public function getData(): string;

This method returns the raw PDF data as a string.

Implicit Inference

If you would prefer to not call build(), you can simply omit it and call the methods that are available on the Output class. The service will implicitly build the PDF for you, and then call the applicable method on the output.

Preparing the Source

With the basics out of the way, let’s talk more about preparing the source. The prepareSource method takes a single argument that represents your source data.

Here’s the method signature:

use WeasyPrint\Objects\Source;
use Illumintate\Support\Contracts\Renderable;

public function prepareSource(Source|Renderable|string $source): static

The $source argument may be one of the following:

  • WeasyPrint\Objects\Source if you are preparing a Source instance manually. The Source::new constructor accepts a Renderable or a string.
  • Illumintate\Support\Contracts\Renderable if you are passing in an instance of something that is renderable, ie it implements the render method. This might be a Laravel View, which also accepts an array of data. For more information, see the Laravel documentation on views.
  • string if you are passing in an already-rendered piece of HTML, or asking WeasyPrint to fetch and render the source from an external URL.

Source Object

If you would like to use the Source object, you may instantiate it as follows:

use WeasyPrint\Objects\Source;
use WeasyPrint\Facade as WeasyPrint;

$source = Source::new('<p>WeasyPrint rocks!</p>');
$service = WeasyPrint::prepareSource($source);

Renderable

A Renderable is simply a class that implements the Renderable contract, described above.

use Illumintate\Support\Contracts\Renderable;

class MyRenderable implements Renderable
{
  public function render(): string
  {
    return 'string with rendered HTML data…';
  }
}

// …

$service = WeasyPrint::prepareSource(new MyRenderable);

String

If you prefer to pass in a string:

use WeasyPrint\Facade as WeasyPrint;

$service = WeasyPrint::prepareSource('<p>WeasyPrint rocks!</p>');

Attachments

WeasyPrint has the ability to add attachments to output PDFs. To add an attachment, call the addAttachment method:

$service = WeasyPrint::prepareSource('<p>WeasyPrint rocks!</p>')
  ->addAttachment('/absolute/path/to/attachment');
  ->addAttachment('/as/many/as/you/like');

Naturally this has no effect when outputting to PNG.

Configuration

As mentioned in previous sections, you may change WeasyPrint’s configuration on the fly, either by passing a configuration object to the new method of the service class, or by calling mergeConfig on an already-resolved service class instance.

Named Parameters and Argument Unpacking

Both of these methods use argument unpacking to internally resolve a new instance of WeasyPrint\Config, which will be used by the service class instance to interpret the configuration options as and when needed.

Given that WeasyPrint for Laravel requires PHP 8 to run, you may pass in the configuration options as named arguments to either of these methods:

$service->mergeConfig(
  binary: '/absolute/path/to/weasyprint',
  timeout: 5000,
);

If you prefer, however, you may also pass in an unpacked array:

$service->mergeConfig(...[
  'binary' => '/absolute/path/to/weasyprint',
  'timeout' => 5000,
])

Merging with the Defaults

No matter which way you pass in the configuration options, they will be merged with the defaults, which are acquired from the default configuration stored in the package source, or from the published config file if you ran vendor:publish.

Available Configuration Options

Here are the configuration options you can set, along with their defaults:

return [

  /**
   * The path to the WeasyPrint binary on your system.
   * If it is available on your system globally, the package will find and use it.
   * If not, then you will need to specify the absolute path.
   * @param string
   */
  'binary' => env('WEASYPRINT_BINARY'),

  /**
   * The environment variables passed to Symfony Process when
   * executing the WeasyPrint binary.
   * @param array
   */
  'processEnvironment' => ['LC_ALL' => env('WEASYPRINT_LOCALE', 'en_US.UTF-8')],

  /**
   * The cache prefix to use for the temporary filename.
   * @param string
   */
  'cachePrefix' => env('WEASYPRINT_CACHE_PREFIX', 'weasyprint_cache'),

  /**
   * The amount of seconds to allow a conversion to run for.
   * @param int
   */
  'timeout' => env('WEASYPRINT_TIMEOUT', 120),

  /**
   * Force the input character encoding. utf-8 is recommended.
   * @param string
   */
  'inputEncoding' => env('WEASYPRINT_INPUT_ENCODING', 'utf-8'),

  /**
   * Enable or disable HTML Presentational Hints.
   * When enabled, `--presentational-hints` is passed to the binary.
   * @param bool
   */
  'presentationalHints' => env('WEASYPRINT_PRESENTATIONAL_HINTS', true),

  /**
   * Optionally set the media type to use for CSS @media.
   * Defaults to `print` at binary-level.
   * @param string|null
   */
  'mediaType' => env('WEASYPRINT_MEDIA_TYPE'),

  /**
   * Optionally set the base URL for relative URLs in the HTML input.
   * Defaults to the input’s own URL at binary-level.
   * @param string|null
   */
  'baseUrl' => env('WEASYPRINT_BASE_URL'),

  /**
   * Optionally provide an array of stylesheets to use alongside the HTML input.
   * Each stylesheet may the absolute path to a file, or a URL.
   * It is recommended to do this at runtime.
   * @param string[]|null
   */
  'stylesheets' => null,

  /**
   * Optionally enable size optimizations, where WeasyPrint will attempt
   * to reduce the size of embedded images, fonts or both.
   * Use: 'images', 'fonts', 'all' or 'none' (default)
   * @param string
   */
  'optimizeSize' => env('WEASYPRINT_OPTIMIZE_SIZE', 'none'),

];

As noted before, you may publish the config file if you’d like to make changes to it – but, in most cases, you’ll want to make use of environment variables by adding them to your .env file or using whatever mechanism your app uses to resolve them.

TL;DR, gimme a cheat-sheet!

Here's a cheat-sheet showing all possible approaches and scenarios.

// Managing Config
$service = WeasyPrint\Service::new(binary: '/bin/weasyprint');
$service = WeasyPrint\Service::new(...['binary' => '/bin/weasyprint']);
$service = WeasyPrint\Facade::mergeConfig(binary: '/bin/weasyprint');
$service = WeasyPrint\Facade::mergeConfig(...['binary' => '/bin/weasyprint']);

// Preparing the Source
$service = WeasyPrint\Service::new()->prepareSource('Cheat-sheet!');
$service = WeasyPrint\Service::createFromSource('Cheat-sheet!');
$service = WeasyPrint\Facade::prepareSource('Cheat-sheet!');
$service = app(WeasyPrint\Factory::class)::prepareSource('Cheat-sheet!');

// Using Explicit calls to build()
$service->build()->download('document.pdf');
$service->build()->inline('document.pdf');
$service->build()->putFile('document.pdf', 'disk-name');
$service->build()->getData();

// Using Implicit Output Inference
$service->download('document.pdf');
$service->inline('document.pdf');
$service->putFile('document.pdf', 'disk-name');
$service->getData();

Contributing

If you’d like to make a contribution to WeasyPrint for Laravel, you’re more than welcome to submit a merge request against the main or current-release branch:

  1. If you are introducing a non-breaking change and supports WeasyPrint < v53 (cairo), target the 5.x branch.
  2. If you are introducing a non-breaking change and supports WeasyPrint ≥ v53 (pydyf), target the 6.x branch.
  3. If you are introducing a breaking change of any kind, target the main branch. The change will be released in a new major version when accepted.

Your request should be as detailed as possible, unless it’s a trivial change.

Tests

Should it be required, please make sure that any impacted tests are updated, or new tests are created.

  1. If you are introducing a new feature, you will more than likely need to create a new test case where each piece of fuctionality the new feature introduces may be tested.
  2. Otherwise, if you are enhancing an existing feature by adding new functionality, you may add the appropriate test method to the applicable test case.

When building tests, you do not need to build them for each instantiation type. Like other tests in the suite, you may use direct service-class instantiation.

Then run the tests before opening your merge request:

$ composer run test

This will run tests in parallel. To run them sequentially, run this instead:

$ ./vendor/bin/testbench package:test

Commit Messages

Your commit message should be clear and concise. If you’re fixing a bug, start the message with bugfix:. If it’s a feature: feature:. If it’s a chore, like formatting code: chore:.

If you’d simply like to report a bug or request a feature, simply open an issue.

Open Source

Licensed under ISC, WeasyPrint for Laravel is an open-source project, and is free to use. In fact, it will always be open-source, and will always be free to use. Forever. 🎉

If you would like to support the development of WeasyPrint for Laravel, please consider making a small donation via PayPal.

You might also like...
DOMPDF module for Laravel 5

pdf-laravel5 DOMPDF module for Laravel 5. Export your views as PDFs - with css support. Instalation Add: "vsmoraes/laravel-pdf": "^2.0" To your compo

Generate PDF invoices for your customers in laravel
Generate PDF invoices for your customers in laravel

What is Invoices? Invoices is a Laravel library that generates a PDF invoice for your customers. The PDF can be either downloaded or streamed in the b

Rapidly Generate Simple Pdf, CSV, & Excel Report Package on Laravel
Rapidly Generate Simple Pdf, CSV, & Excel Report Package on Laravel

Laravel Report Generators (PDF, CSV & Excel) Rapidly Generate Simple Pdf Report on Laravel (Using barryvdh/laravel-dompdf or barryvdh/laravel-snappy)

Laravel package to convert HTML to PDF, supporting multiple drivers.

eve/pdf-converter A Laravel package to help convert HTML to PDF. Supports multiple drivers. Requirements and Installation eve/pdf-converter requires L

Dompdf - Simple Dompdf package for Laravel

Dompdf - Simple Dompdf package for Laravel

Ce projet vous montre comment utiliser des fonts localement dans vos applications Laravel, avec ViteJS et Tailwind CSS

Laravel - use local fonts with Tailwind CSS and Vite Ce projet est né d'un constat: vous êtes souvent nombreuses et nombreux à galérer pour utiliser d

PHP library allowing PDF generation or snapshot from an URL or an HTML page. Wrapper for Kozea/WeasyPrint

PhpWeasyPrint PhpWeasyPrint is a PHP library allowing PDF generation from an URL or an HTML page. It's a wrapper for WeasyPrint, a smart solution help

Document templates Laravel package is intended for creating/managing user editable document template
Document templates Laravel package is intended for creating/managing user editable document template

Document Templates Introduction Document templates Laravel package is intended for creating/managing user editable document templates, with ability to

Lightweight and feature-rich PHP validation and filtering library. Support scene grouping, pre-filtering, array checking, custom validators, custom messages. 轻量且功能丰富的PHP验证、过滤库。支持场景分组,前置过滤,数组检查,自定义验证器,自定义消息。

PHP Validate 一个简洁小巧且功能完善的php验证、过滤库。 简单方便,支持添加自定义验证器 支持前置验证检查, 自定义如何判断非空 支持将规则按场景进行分组设置。或者部分验证 支持在进行验证前对值使用过滤器进行净化过滤内置过滤器 支持在进行验证前置处理和后置处理独立验证处理 支持自定义每

A simple, yet feature rich password manager for Nextcloud

Easy to use yet feature-rich and secure password manager for Nextcloud

ExpressionEngine is a flexible, feature-rich, free open-source content management platform that empowers hundreds of thousands of individuals and organizations around the world to easily manage their web site.
ExpressionEngine is a flexible, feature-rich, free open-source content management platform that empowers hundreds of thousands of individuals and organizations around the world to easily manage their web site.

ExpressionEngine CMS ExpressionEngine is a mature, flexible, secure, free open-source content management system. It is beloved by designers for giving

A discord-feature rich API plugin for PMMP.

DiscordBot DiscordBot a core plugin that provides an extensive API for plugins to interact with a discord bot creating endless possibilities. Examples

Build lightning-fast and feature-rich websites with ProcessWire.

WIREKIT Core Build lightning-fast and feature-rich websites with ProcessWire. Website: wirekit.dev (in plans) Demo: start.wirekit.dev/core/ Updates: W

A wrapper around faker for factory muffin

Factory Muffin Faker 2.3 The goal of this package is to wrap Faker to make it super easy to use with Factory Muffin. Note that this library does not a

A Symfony Feature Flag Bundle which easily allows you to configure and use your favorite feature flag provider.

Metro Markets FF Metro Markets FF is a Feature Flag Symfony Bundle. It easily allows you to configure and use your favorite feature flag provider. Ins

Laravel 5 Model Factory Generator

Laravel 5 Model Factory Generator This package offers a lazy way to create a new model factory files, since Laravel ( 5.5) have no Artisan command to

🏭This package lets you create factory classes for your Laravel project.
🏭This package lets you create factory classes for your Laravel project.

Laravel Factories Reloaded 🏭 This package generates class-based model factories, which you can use instead of the ones provided by Laravel. Laravel 8

Declare database migrations and factory definitions inside Laravel models.

Lucid This package allows you to declare database migrations and factory definitions inside of your Laravel models. Running the lucid:migrate command

This package provides the database factory experience to fake Http calls in your testsuite.
This package provides the database factory experience to fake Http calls in your testsuite.

This package provides the database factory experience to fake Http calls in your testsuite

Comments
  • Fix branching on `$value` in Command::maybePushArgument method

    Fix branching on `$value` in Command::maybePushArgument method

    What kind of change does this PR introduce? Bugfix

    What is the new behavior? Fix bug related to checks on a true/thruty value.

    Does this PR introduce a breaking change? No

    Other information: After updating a project to laravel 9 and using dev-main weasyprint package version for compatibility, pdf could not render fonts properly. Checking every change on dev-main, we found out the thing that was causing the breaking behavior was a match in Command.php at maybePushArgument method: https://github.com/mikerockett/weasyprint/blob/1c3e4a9328199c5c5594bba6212565849309846d/src/Command.php#L52 branch 6.x version checks for true values and thruty values leaving out falsy values:

    if ($value === true) {
          $this->arguments->push($key);
    } else if ($value) {
          $this->arguments->push($key, $value);
    }
    

    dev-main version with match threats every value that isn't strictly boolean true equally. Our proposed change restores previous behavior.

    opened by AngeloAdd 2
Owner
Mike Rockétt
Building all of the things. Passionate about open-source.
Mike Rockétt
A DOMPDF Wrapper for Laravel

DOMPDF Wrapper for Laravel Laravel wrapper for Dompdf HTML to PDF Converter Require this package in your composer.json and update composer. This will

Barry vd. Heuvel 5.6k Jan 7, 2023
Browsershot wrapper for Laravel 5

Browsershot wrapper for Laravel 5 This package takes advantage of Google Chrome's Headless mode to take screenshots and generate PDFs from websites, v

VECO 108 Jul 25, 2022
PHP library allowing thumbnail, snapshot or PDF generation from a url or a html page. Wrapper for wkhtmltopdf/wkhtmltoimage

Snappy Snappy is a PHP library allowing thumbnail, snapshot or PDF generation from a url or a html page. It uses the excellent webkit-based wkhtmltopd

KNP Labs 4.1k Dec 30, 2022
A slim PHP wrapper around wkhtmltopdf with an easy to use and clean OOP interface

PHP WkHtmlToPdf PHP WkHtmlToPdf provides a simple and clean interface to ease PDF and image creation with wkhtmltopdf. The wkhtmltopdf and - optionall

Michael Härtl 1.5k Dec 25, 2022
Simple wrapper package around MPDF's setProtection method that allows you to set password on PDF files

Laravel PDF Protect (fork) Simple wrapper package around MPDF's setProtection method that allows you to set password on PDF files. Installation You ca

Raphael Planer 2 Jan 23, 2022
PHP Wrapper for callas pdfToolbox

PHP Wrapper for callas pdfToolbox A PHP wrapper class for callas pdfToolbox. Installation This library is installed via Composer. To install, use comp

Alannah Kearney 0 Feb 5, 2022
Laravel Snappy PDF

Snappy PDF/Image Wrapper for Laravel 5 and Lumen 5.1 This package is a ServiceProvider for Snappy: https://github.com/KnpLabs/snappy. Wkhtmltopdf Inst

Barry vd. Heuvel 2.3k Jan 2, 2023
Adobe XDでデザインしてSVGでエクスポートしたテンプレートをもとに、A4サイズの帳票をHTMLで出力する機能のPHP(Laravel)による実装例です

svg-paper-example Adobe XDでデザインしてSVGでエクスポートしたテンプレートをもとに、A4サイズの帳票をHTMLで出力する機能のPHP(Laravel)による実装例です。 こちらで実際に動くデモが見られます ?? 実装内容についての詳細は こちらのブログ記事 で解説していま

Takashi Kanemoto 21 Dec 11, 2022
Generate PDFs in Laravel with Mpdf.

Laravel Mpdf: Using Mpdf in Laravel for generate Pdfs Easily generate PDF documents from HTML right inside of Laravel using this mpdf wrapper. Importa

Carlos Meneses 264 Jan 4, 2023
A Laravel package for creating PDF files using LaTeX

LaraTeX A laravel package to generate PDFs using LaTeX · Report Bug · Request Feature For better visualization you can find a small Demo and the HTML

Ismael Wismann 67 Dec 28, 2022