Verified Commit a0ce4af0 authored by Mike Rockétt's avatar Mike Rockétt 💬
Browse files

v6: updates to changelog, config, readme and upgrade guide

parent cabc0422
Pipeline #346097045 passed with stage
in 47 seconds
<img width="400" src="logo.png" alt="WeasyPrint for Laravel" />
# WeasyPrint for Laravel – Release Notes
---
## v6.0.0 (Breaking Release) `current`
# Release Notes
This version is specifically designed around WeasyPrint v53, which drops support for PNGs due to its new rendering engine. Overall, this simplifies things from an interface perspective – you only need to prepare the source, build the `Output`, and do what you need with it.
## v5.0.0 (Major Paradigm Release) `current`
Over and above the changes noted below, the package now requires Laravel 8.47+, which adds support for [scoped singletons](https://laravel.com/docs/8.x/container#binding-scoped). In the previous version (v5) of this package, the singleton was immutable, which meant that every mutable-by-design method would actually return a cloned instance of the service.
### What’s New
- The configuration file now supports environment variables, which generally removes the need to publish it. See the [readme](readme.md#available-configuration-options) for a list of available options.
### Breaking Changes
- The `to()`, `toPdf()` and `toPng()` methods have been removed.
- Likewise, the `OutputType` enumeration class has been removed. Under the hood, the `--format` flag has been removed.
- The `optimizeImages` config option has been removed in favor of `optimizeSize`.
- The `resolution` config option has been removed, due to lack of PNG support.
### Other Changes
- The `binary` config option previously declared a sensible default of `/usr/local/bin/weasyprint`. However, this may not always be the case as WeasyPrint may be installed in a virtual environment, which does not conform to that path. Additionally, some Linux distros place the binary elsewhere on the system. With the removal of this default, the package will attempt to locate the binary, which means it needs to be in your `PATH`. If it is not in your path, and you do not want it to be, simply set the absolute path to the binary in your environment using `WEASYPRINT_BINARY`.
- Due to the addition of the scoped singleton, the service class is no longer immutable. Any method that previously cloned the service will no longer do so.
- Internally, the package now uses a [pipeline](https://github.com/mikerockett/pipeline) to prepare everything and call the WeasyPrint binary.
## v5.0.0 (Paradigm Release) `maintenance`
### What’s New
......
......@@ -5,7 +5,7 @@ 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 specifu the absolute path.
* If not, then you will need to specify the absolute path.
* @param string
*/
'binary' => env('WEASYPRINT_BINARY'),
......
<img width="400" src="logo.png" alt="WeasyPrint for Laravel" />
# WeasyPrint for Laravel
---
![License](https://img.shields.io/packagist/l/rockett/weasyprint?style=for-the-badge)
![Version](https://img.shields.io/packagist/v/rockett/weasyprint?label=Release&style=for-the-badge)
![Downloads](https://img.shields.io/packagist/dm/rockett/weasyprint?label=Installs&style=for-the-badge)
![Pipeline Status](https://img.shields.io/gitlab/pipeline/mikerockett/weasyprint/master?style=for-the-badge)
A feature-rich Laravel wrapper for the [WeasyPrint Document Factory](https://weasyprint.org/).
**A feature-rich Laravel wrapper for the [WeasyPrint Document Factory](https://weasyprint.org/).**
**Note:** This package requires **Laravel 8+** running on **PHP 8+** in order to operate.
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](https://laravel.com/docs/8.x/container#binding-scoped), which adds first-class support for [Laravel Octane](https://github.com/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.
[Changelog](changelog.md) | [Upgrade Guide](upgrading.md)
See the **[Changelog](changelog.md)** | View the **[Upgrade Guide](upgrading.md)**
# Table of Contents
---
- [Package Installation](#package-installation)
- [Service Instantiation](#service-instantiation)
......@@ -16,18 +19,16 @@ A feature-rich Laravel wrapper for the [WeasyPrint Document Factory](https://wea
- [Option 2. Dependency Injection](#option-2-dependency-injection)
- [Option 3. Facade](#option-3-facade)
- [Building the Output](#building-the-output)
- [Explicit Output Type](#explicit-output-type)
- [Implicit Inference](#implicit-inference)
- [Output Methods](#output-methods)
- [Preparing the Source](#preparing-the-source)
- [Source Object](#source-object)
- [Renderable](#renderable)
- [String](#string)
- [Attachments](#attachments)
- [Attachments](#attachments)
- [Configuration](#configuration)
- [Named Parameters and Argument Unpacking](#named-parameters-and-argument-unpacking)
- [Merging](#merging)
- [Merging with the Defaults](#merging-with-the-defaults)
- [Available Configuration Options](#available-configuration-options)
- [Immutability](#immutability)
- [TL;DR, gimme a cheat-sheet!](#tldr-gimme-a-cheat-sheet)
- [Contributing](#contributing)
- [Tests](#tests)
......@@ -46,7 +47,7 @@ $ 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 following command:
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.
```shell
$ php artisan vendor:publish --tag=weasyprint.config
......@@ -99,9 +100,7 @@ class GeneratePDF
}
```
To use dependency injection, you need to use the Factory contract, which will resolve the WeasyPrint service singleton from the [Service Container](https://laravel.com/docs/container). This singleton is prepared with your default configuration at framework boot-time, and is fully compatible with [Laravel Octane](https://github.com/laravel/octane).
The service singleton is immutable, which means that calls to `prepareSource`, `mergeConfig`, `addAttachment`, `to`, `toPdf`, and `toPng` will return a **newly cloned service instance**. See the notes on [immutability](#immutability) for more information.
To use dependency injection, you need to use the Factory contract, which will resolve the WeasyPrint service singleton from the [Service Container](https://laravel.com/docs/container). This singleton is scoped to ensure support for [Laravel Octane](https://github.com/laravel/octane).
To reconfigure this instance, you may call `mergeConfig` on the new service instance:
......@@ -123,87 +122,47 @@ $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. From this point, the behaviour remains exactly as it would with dependency injection. That is, you will receive a newly cloned instance of the service when any of the prior methods are called. See the notes on [immutability](#immutability) for more information.
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. This package supports everything WeasyPrint supports, which means you can build to PDF or PNG. This output type may be declared explicitly, or inferred implicitly from the filename.
### Explicit Output Type
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`.
```php
use WeasyPrint\Enums\OutputType;
$outputPdf = $service->to(OutputType::pdf())->build(); // this is the default
$outputPng = $service->to(OutputType::png())->build();
// Getting the output type from a string (useful when this is user-input)
$outputPng = $service->to(OutputType::from('png'))->build();
$output = $service->build();
```
Here, we call the `to` method to set the output type, which must be an instance of the `OutputType` enumeration (Yes, we will support proper enums when PHP 8.1 is released 🎉). Then, we call `build` which spawns a Symfony Process that sends the source to `weasyprint` and returns the result to the service class.
The `build` method will return an instance of `WeasyPrint\Objects\Output`, which holds a resource pointing to the built output. With this, you may stream the content of the output as a download or an inline attachment, save it to a filesystem, or simply retrieve the string (more on this further down).
Note that `pdf` is the default output type. As such, calling `build` before declaring an output type will always output a PDF.
#### Shorthand
You may also set the output type using the shorthand methods:
The `$output` object makes the following methods available:
```php
$outputPdf = $service->toPdf()->build();
$outputPng = $service->toPng()->build();
public function download(string $filename, array $headers = [], bool $inline = false): StreamedResponse;
```
### Implicit Inference
This method creates a Symfony `StreamedResponse` that may be used to download the PDF to the client (browser).
```php
$outputPdf = $service->download('document.pdf');
$outputPng = $service->inline('document.png');
public function inline(string $filename, array $headers = []): StreamedResponse;
```
If you would prefer to not specify the output type and then build manually, you may simply call the appropriate return-method, like `download` or `inline` (discussed below). When you do this, the output type will be inferred from the file extension.
When doing this, the `to` and `build` methods will be called on your behalf, unless you have already called them.
### Output Methods
Once you have built the output, there are several things you can do with it:
1. Stream it as a download to the browser.
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`.
```php
$service->to(OutputType::pdf())->build()->download('document.pdf');
public function putFile(string $path, ?string $disk = null, array $options = []): bool;
```
2. Inline it as an attachment.
This method forwards the data to Laravel’s [Filesystem](https://laravel.com/docs/filesystem) using the `Storage` facade’s `put` method, which gives you the ability to save the PDF to disk.
```php
$service->to(OutputType::pdf())->build()->inline('document.pdf');
public function getData(): string;
```
3. Save it to disk.
```php
$service->to(OutputType::pdf())->build()->putFile('documents/document.pdf', 's3', $options = []);
```
The `putFile` method, which forwards the operation to Laravel’s filesystem, accepts a the following arguments:
- A path relative to the root of your disk, not just a file name
- A specific Laravel Filesystem disk, such as `s3`. If you don’t provide this, the default disk will be used.
- Options to be passed to `put` on the disk instance.
4. Grab it and do what you want with it.
This method returns the raw PDF data as a string.
```php
$service->to(OutputType::pdf())->build()->getData(); // You can also call getContentType to get the MIME type.
```
### Implicit Inference
Note that, in these examples, we are declaring the output type explicitly. This means that the implicit inference mechanism will not be triggered when you specify the file name. As such, if you were to provide an extension that does not match up with the output type, the package will just assume that you know what you're doing and proceed, no questions asked.
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
......@@ -212,9 +171,10 @@ With the basics out of the way, let’s talk more about preparing the source. Th
Here’s the method signature:
```php
public function prepareSource(
WeasyPrint\Objects\Source|Illumintate\Support\Contracts\Renderable|string $source,
): static
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:
......@@ -235,6 +195,26 @@ $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.
```php
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:
......@@ -245,7 +225,7 @@ use WeasyPrint\Facade as WeasyPrint;
$service = WeasyPrint::prepareSource('<p>WeasyPrint rocks!</p>');
```
### Attachments
## Attachments
WeasyPrint has the ability to add attachments to output PDFs. To add an attachment, call the `addAttachment` method:
......@@ -283,7 +263,7 @@ $service->mergeConfig(...[
])
```
### Merging
### 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`.
......@@ -295,81 +275,79 @@ Here are the configuration options you can set, along with their defaults:
return [
/**
* The absolute path to the WeasyPrint binary on your system.
* 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' => '/usr/local/bin/weasyprint',
'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' => 'weasyprint_cache',
'cachePrefix' => env('WEASYPRINT_CACHE_PREFIX', 'weasyprint_cache'),
/**
* The amount of seconds to allow a conversion to run for.
* @param int
*/
'timeout' => 3600,
'timeout' => env('WEASYPRINT_TIMEOUT', 120),
/**
* Force the input character encoding. utf-8 is recommended.
* @param string
*/
'inputEncoding' => 'utf-8',
'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' => true,
/**
* Optionally enable image optimization, where WeasyPrint will attempt
* to reduce the size of embedded images.
* When enabled, `--optimize-images` is passed to the binary.
* Note: this feature requires WeasyPrint 52 or greater.
* @param bool
*/
'optimizeImages' => false,
/**
* Optionally set the output resolution in pixels per inch.
* For PNG output only. Defaults to 96 (which means that PNG pixels match CSS pixels) at binary-level.
* @param int|null
*/
'resolution' => null,
'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' => 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' => 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'),
];
```
## Immutability
Under the hood, the service class is immutable. This means that every time you prepare a source, change configuration, or set the output format, the service is cloned. The idea here is that the base service is only created once per request, as a singleton, and actual conversion-related actions on the service are done in a fresh instance, created solely for the purpose of that conversion.
This provides additional benefits for stateful servers like [Laravel Octane](https://github.com/laravel/octane), where the base service is only ever created once with the default configuration. When a request terminates, cloned instances will be disposed of.
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!
......@@ -388,21 +366,17 @@ $service = WeasyPrint\Service::createFromSource('Cheat-sheet!');
$service = WeasyPrint\Facade::prepareSource('Cheat-sheet!');
$service = app(WeasyPrint\Factory::class)::prepareSource('Cheat-sheet!');
// Using Explicit Output Types
$service->to(OutputType::pdf())->build()->download('document.pdf')
$service->to(OutputType::from('pdf'))->build()->download('document.pdf')
$service->to(OutputType::png())->build()->inline('image.png')
$service->to(OutputType::pdf())->build()->getData()
// Using Explicit Output Types (Shorthand)
$service->toPdf()->build()->download('document.pdf')
$service->toPng()->build()->inline('document.png')
$service->toPdf()->build()->getData()
// Using Implicit Type Inference (OutputType determined by extension)
$service->download('document.pdf')
$service->inline('image.png')
$service->getData() // No filename here, so PDF will be used by default.
// 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
......
<img width="400" src="logo.png" alt="WeasyPrint for Laravel" />
# WeasyPrint for Laravel – Upgrade Guide
---
## v5 → v6
Version 6 of the package is a trimmed down version of v5, with specific emphasis on support for WeasyPrint v53, which has a new rendering engine (drops cairo) and no longer supports PNG images.
To upgrade to v6 of the package, you must be running WeasyPrint v53 or greater. A varity of installation options are available on their [documentation](https://doc.courtbouillon.org/weasyprint/latest/first_steps.html).
This version drops support for output types, as only PDFs are supported now. This means that the `to()`, `toPdf()` and `toPng()` methods have been dropped. The `OutputType` enumeration class has also been dropped.
The instantiation options are still available, however you no longer need to call any of the above methods. For example, assuming you are using the Facade, you can now do the following:
```php
// Download
WeasyPrint::prepareSource($source)->build()->download('filename.pdf'); // or,
WeasyPrint::prepareSource($source)->download('filename.pdf');
// Inline
WeasyPrint::prepareSource($source)->build()->inline('filename.pdf'); // or,
WeasyPrint::prepareSource($source)->inline('filename.pdf');
// Get Raw Data
$data = WeasyPrint::prepareSource($source)->build()->getData(); // or,
$data = WeasyPrint::prepareSource($source)->getData();
```
Be sure to checkout the [readme](readme.md) to see all the instantiation approaches.
Additionally, some configuration options have changed:
- `resolution` has been dropped – this was for PNGs only. You may remove this option if you have published your config file.
- `optimizeImages` has been dropped in favor of `optimizeSize`, corresponding to the `--optimize-size` flag that is passed to WeasyPrint. You don't need to do anything if you have not published your config file. If you have, simply remove `optimizeImages` and replace it with `optimizeSize`, as follows:
```php
return [
// …
/**
* 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'),
];
```
Note that the configuration now supports environment variables, which means you don't need to publish the config file anymore, unless you'd like to change the variable names or resolve them in a different way. See the [readme](readme.md) for more information.
# Upgrade Guide
And, lastly, the `getContentType()` method on the `Output` class has been removed – you will always receive `application/pdf`.
## v2/3/4 → v5.0.0
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment