Word Developer guide
This module adds the ability to upload Word templates, parse them, and convert them
Installation
To install this module:
composer require qore/templates-extended
php artisan vendor:publish --tag=qore.templates-extended.db
php artisan vendor:publish --tag=qore.templates-extended.frontend
Optionally, publish the config:
php artisan vendor:publish --tag=qore.templates-extended.config
Make sure to migrate.
php artisan tenants:migrate
Menu
The WordTemplateResource
will be registered by default. You can add this to your menu:
if (module_is_active('qore/templates-extended')) {
$tab->addResourceMenuItem(resource(WordTemplateResource::class));
}
This module also comes with a generic Templates
page, where you have a shortcut to
- Word templates
- Twig templates
- Mail templates
- Template builder (todo)
if (module_is_active('qore/templates-extended')) {
$tab->addMenuItem(
'Sjablonen',
'/document-layouts',
['settings management'],
function(MenuItem $item) {
$item->setIcon('integration_instructions');
}
);
}
LibreOffice & Toolbox
After activating this module, you can go to the settings page and determine what driver you would like to use for converting files.
Converting a Word template to other file types like PDF
, PNG
etc. will require the software LibreOffice
:
- Toolbox API (recommended for development). LibreOffice will be installed elsewhere (currently:
https://toolbox.qlic.nl
), see also: https://github.com/baaskoen/toolbox. - Local
LibreOffice
installation. You will be required to install the software and point the correct path to thesoffice
binary inconfig/templates.php
(if you have published it). By default it will use your.env
:LIBREOFFICE_BINARY='/Applications/LibreOffice.app/Contents/MacOS/soffice'
Usage
This module uses PHPWord
to modify & parse Word files. Make sure to read their docs if you're not sure how to add something.
Setting up your resource
Every WordTemplate
is linked to one of your resources, in order to retrieve its available tags and mapping for conversion, you need to add the following interface to your resource:
class TicketResource extends QoreResource implements ResourceExportsToWord
Next, you need to determine what tags will be available in the word template:
public function getWordTags(): array
{
return (new DefaultResourceWordTags($this, [
'ticket_name' => 'Ticket title',
'ticket_category' => 'Ticket category',
]))->toArray();
}
You can also just return a key
=> value
pair array. The reason why a class is given here, is to also append your resource fields as tags.
Finally, you will need to map your given tags to values, and also do additional parsing if needed:
public function exportToWord(WordExport $export): WordExport
{
/** @var Ticket $model */
$model = $export->getModel();
$export->setVariables([
'ticket_name' => $model->name,
'ticket_category' => ucfirst($model->category)
]);
$export->renderWordTags('ticket_name', 'ticket_category');
return $export;
}
Working with tables
When dealing with for example invoices or quotations, you often have repeatable rows inside tables like invoice lines.
In order to make this work, you should define some tags, and mark them as repeatable like this:
public function getWordTags(): array
{
return (new DefaultResourceWordTags($this, [
'table_1_row_number' => 'Row number for first table rows (repeated)',
'table_1_message_id' => 'Ticket message ID for first table rows (repeated)',
'table_1_message_description' => 'Ticket message description for first table rows (repeated)',
]))->toArray();
}
public function exportToWord(WordExport $export): WordExport
{
/** @var Ticket $model */
$model = $export->getModel();
$processor = $export->getProcessor();
if (in_array('table_1_row_number', $processor->getVariables())) {
$processor->cloneRow('table_1_row_number', $model->ticketMessages->count());
$counter = 1;
foreach ($model->ticketMessages as $message) {
$processor->setValue('table_1_row_number#' . $counter, $counter);
$processor->setValue('table_1_message_id#' . $counter, $message->id);
$processor->setValue('table_1_message_description#' . $counter, $message->description);
$counter++;
}
}
return $export;
}
Appending Images
You can also append images with the processor:
public function exportToWord(WordExport $export): WordExport
{
/** @var Ticket $model */
$model = $export->getModel();
$processor = $export->getProcessor();
$processor->setImageValue('signature', [
'path' => $model->getFirstMediaPath(),
'width' => 300,
'height' => 300
]);
//
}
Appending HTML
Similar to appending images, you can also append HTML:
public function exportToWord(WordExport $export): WordExport
{
/** @var Ticket $model */
$model = $export->getModel();
$processor = $export->getProcessor();
$this->processor->setHtmlBlockValue(
'my_html',
'<h1>Hello world</h1>'
);
//
}
Creating Global tags
The config/templates.php
adds some tags that can be used in every Word template (like ${PAGE_BREAK}
).
You can append your own Global tag here, by creating a class that extends GlobalTag
:
<?php
class AddressBlock extends GlobalTag
{
public function description(): string
{
return __('My description');
}
public function tag(): string
{
return 'MY_TAG';
}
public function run(WordExport $export): void
{
while (in_array($this->tag(), $export->getProcessor()->getVariables())) {
$block = new TextRun();
$block->addText('Hello world');
$block->addTextBreak();
$export->getProcessor()->setComplexValue($this->tag(), $block);
}
}
}
Upgrade Guide
To upgrade this module:
composer update qore/templates-extended
If you need to upgrade migrations or Vue components:
php artisan vendor:publish --tag=qore.templates-extended.db --force
php artisan vendor:publish --tag=qore.templates-extended.frontend --force