chanthoeun / filament-document-builder
A Filament plugin for building dynamic documents and exporting to PDF.
Package info
github.com/Chanthoeun/filament-document-builder
pkg:composer/chanthoeun/filament-document-builder
Requires
- php: ^8.2
- amidesfahani/filament-tinyeditor: ^4.0|^5.0
- carlos-meneses/laravel-mpdf: ^2.1
- filament/filament: ^4.0|^5.0
- illuminate/contracts: ^10.0|^11.0|^12.0|^13.0
- illuminate/support: ^10.0|^11.0|^12.0|^13.0
Requires (Dev)
- larastan/larastan: ^3.10
- orchestra/testbench: ^11.1
- phpstan/phpstan: ^2.2
README
A powerful and simplified Filament PHP plugin to build dynamic document templates (like invoices, certificates, and registration forms) using a full-featured TinyMCE editor, and automatically export them to PDFs with native support for complex scripts like Khmer.
It is designed to easily integrate with standalone Filament panels or with other plugins like chanthoeun/filament-custom-forms.
Features
- Advanced HTML Designer: Uses
amidesfahani/filament-tinyeditor(TinyMCE) instead of the native Tiptap editor to provide robust support for complex HTML structures and native table editing. - Dynamic Variables: Inject runtime database values directly into your text blocks (e.g.,
{{ customer.name }}). Fallbacks safely to a blank space if data is missing (perfect for printing blank forms). - Native PDF Engine: Powered by
carlos-meneses/laravel-mpdf(mPDF) for pure PHP generation. - Complex Text Shaping: Pre-configured with
autoScriptToLangandautoLangToFontto perfectly render complex alphabets like Khmer natively, without needing headless Chrome or Puppeteer. - Easy Integration: Drop a simple
Actiononto any Filament table to export the current record as a PDF. - Support for Filament v4 & v5 (Laravel 10-13).
Installation
1. Requirements
- PHP 8.2+
- Filament v4.0 or v5.0
- TinyMCE (
amidesfahani/filament-tinyeditor) - mPDF (
carlos-meneses/laravel-mpdf)
(Note: Node.js, Puppeteer, and Chromium are no longer required!)
2. Install via Composer
composer require chanthoeun/filament-document-builder
3. Publish & Run Migrations
You can publish the migration file to customize the table prefix or structure before running it:
php artisan vendor:publish --tag="filament-document-builder-migrations"
After publishing, run the migrations to create the document_templates table:
php artisan migrate
4. Register the Plugin
Add the plugin to your Filament Panel provider (app/Providers/Filament/AdminPanelProvider.php):
use Chanthoeun\FilamentDocumentBuilder\DocumentBuilderPlugin; public function panel(Panel $panel): Panel { return $panel ->plugin( DocumentBuilderPlugin::make() // Optional: Customize or remove the navigation group // ->navigationGroup('Custom Group') // Move to another group // ->navigationGroup(false) // Remove from groups entirely // ->navigationIcon('heroicon-o-document-text') // Change the navigation icon ); }
Configuration & Publishing
Because this plugin is built with Spatie\LaravelPackageTools, all publishing logic is wired up natively.
1. Publishing the Config File
To customize default paper sizes, orientations, and margins, publish the config file:
php artisan vendor:publish --tag="filament-document-builder-config"
This will create config/filament-document-builder.php in your application.
2. Publishing Translations
To override the default English and Khmer language files, run:
php artisan vendor:publish --tag="filament-document-builder-translations"
3. Publishing the Document Template Resource
If you want complete control over the DocumentTemplateResource (e.g., to change its location, permissions, or logic), you can safely publish it to your application by running:
php artisan filament-document-builder:publish-resource
This command intelligently copies the resource files into your app/Filament/Resources directory and automatically updates all namespaces. The plugin will automatically detect that you've published the resource and will gracefully yield control, preventing any conflicts.
Usage
1. Creating a Template
- Navigate to the Document Builder resource in your Filament sidebar.
- Click Create Document Template.
- Set the layout rules (A4, Portrait) in the Template Details tab.
- Construct your document using the Document Designer tab. Because it uses TinyMCE, you can easily insert and modify highly complex HTML tables.
- If you plan to inject dynamic variables, type them using standard brace syntax (e.g.,
Hello {{ name }}!).
Built-in Shapes and Forms Support
This plugin adds several pre-configured shapes to the TinyMCE editor to make designing forms significantly easier:
- Click the Template icon in the toolbar (or use the
Shapesdropdown) to insert pre-made shapes like a Circle Logo Placeholder, a 4x6 Photo Box, a Rounded Rectangle, or a Signature Line. - Keyboard Shortcuts (Text Patterns): You can also quickly insert shapes by typing the following codes and pressing Space:
#logo-> Circular Logo Box#box-> Square Box#photo-> 4x6 Rectangle Photo Box#checkbox-> Small Checkbox#rounded-> Rounded Rectangle#oval-> Oval Shape#sign-> Signature Area with "ហត្ថលេខា / Signature"
Flexbox Support in mPDF
By default, mPDF does not support modern CSS Flexbox (display: inline-flex), which often breaks designs created in TinyMCE. This plugin automatically polyfills Flexbox behaviors (such as inline-flex, align-items, and justify-content) directly in PHP during the export process. Your TinyMCE layouts will render pixel-perfect in the final PDF without requiring complex CSS hacks!
2. Looping over Data (Table Repeaters)
If you need to iterate over an array or Eloquent relationship (like line items on an invoice), you can use the built-in {{#foreach}} syntax directly in your template.
Switch your TinyMCE editor to Source Code (<>) view and wrap your repeating elements like this:
<tbody> {{#foreach items as item}} <tr> <td>{{ item.description }}</td> <td>{{ item.qty }}</td> <td>{{ item.price }}</td> <td>{{ item.total }}</td> </tr> {{/foreach}} </tbody>
- The engine will automatically loop through the
itemsarray or relationship. - You can access properties of each item using the prefix you define (e.g.,
item.). - Bonus: Inside the loop, you still have full access to global variables from the parent record!
Handling Calculations (e.g., Invoices)
The document rendering engine intentionally avoids executing arbitrary PHP code within the template for security and performance reasons. Therefore, you cannot perform inline math like {{ item.qty * item.price }} inside the TinyMCE editor.
To handle calculations such as line totals, taxes, or grand totals, you should use Laravel Eloquent Accessors directly on your models.
Example (Line Item Total):
On your InvoiceItem model, add an accessor:
public function getTotalAttribute() { return $this->qty * $this->price; }
Now, you can simply use {{ item.total }} inside your {{#foreach}} loop!
Example (Invoice Grand Total):
On your parent Invoice model:
public function getGrandTotalAttribute() { return $this->items->sum('total') + $this->tax_amount; }
Then, anywhere in your document, you can output the grand total using {{ grand_total }}.
3. Additional Data Sources (Multi-Model Support)
If your document requires data from multiple independent models (e.g., a student application form that needs global SchoolSettings or a specific Principal user), you can map them entirely through the UI without touching any code!
- In the Template Details tab, click Add to additional data sources.
- Give it a Variable Name (e.g.,
school). - Select the Database Model (e.g.,
App\Models\SchoolSetting) and choose "First Record" or "Latest Record". - The TinyMCE editor will instantly update its Insert Variable dropdown to include all the fields from your new model (e.g.,
school.name,school.address).
The PDF Engine will automatically execute these queries at runtime and securely merge the data into your document!
4. Exporting PDFs from your Resources
To allow users to download a PDF of a specific record or bulk download multiple records, use the built-in Action classes.
Row Action (Single PDF)
Add DownloadPdfAction to your resource's table actions to download individual records:
use Chanthoeun\FilamentDocumentBuilder\Tables\Actions\DownloadPdfAction; public static function table(Table $table): Table { return $table // ... columns ... ->actions([ DownloadPdfAction::make('download_pdf') ->templateType('invoice') // The type string of the template you created // Optional: Customize the filename ->filename(fn ($record) => 'invoice-' . $record->id . '.pdf') // Optional: Pass custom data (defaults to the $record itself) ->recordData(fn ($record) => [ 'name' => $record->customer_name, 'total' => $record->total_amount, ]) ]); }
Page Header Action (Bulk PDF)
Add DownloadAllPdfAction to your List page header to download multiple records at once (combined into a single PDF with pagebreaks):
use Chanthoeun\FilamentDocumentBuilder\Actions\DownloadAllPdfAction; protected function getHeaderActions(): array { return [ DownloadAllPdfAction::make('download_all_pdf') ->templateType('invoice') ->records(fn () => $this->getFilteredTableQuery()->get()) // Provide the records to export ->filename('invoices-export.pdf') ]; }
Changelog
v1.0.15
- Bug Fix: Fixed an issue where the TinyMCE editor did not dynamically resize based on the live
page_settingsconfiguration. - Bug Fix: Bypassed Filament TinyEditor's
wire:ignorecaching to ensure that the "Insert Variable" dropdown accurately populates whenextra_data_sourcesare modified without requiring a page refresh. - Improvement: Set
formatto uppercase prior to sending it to mPDF to ensure strict compatibility.
v1.0.13
- Update README with migration publishing instructions
v1.0.12
- Hide label and remove required validation from content editor
v1.0.11
- Add navigationSort to allow changing menu order
v1.0.10
- Rename data method to recordData to avoid conflict with Filament Actions
v1.0.9
- Fix namespace for Action inheritance
v1.0.8
- Update README with new action instructions
v1.0.7
- Create reusable PDF action classes
v1.0.6
- Add renderMultiple to support bulk PDF generation
v1.0.5
- Fix variable extraction to use CustomFormField model
v1.0.4
- Fix Array to string conversion
v1.0.3
- Fix Action namespace for Filament v4/v5 compatibility
v1.0.2
- Add publish resource command and improve custom forms integration
v1.0.1
- Fix Filament v4 Action namespaces
v1.0.0
- Update composer.json keywords and prepare for Packagist release
License
The MIT License (MIT).