Examples
The examples are executable PHP files under docs/source/examples/.
Each one is executed and asserted by tests/Integration/ExamplesOutputScenarioTest.php,
which also validates the generated artifacts in build/examples/.
Included examples
Expand an example to inspect the source inline.
basic-template.php — compile a simple template with a context variable
<?php
// SPDX-FileCopyrightText: 2026 LibreSign
// SPDX-License-Identifier: AGPL-3.0-or-later
declare(strict_types=1);
use LibreSign\XObjectTemplate\Dto\CompileRequest;
use LibreSign\XObjectTemplate\XObjectTemplateCompiler;
require dirname(__DIR__, 3) . '/vendor/autoload.php';
$projectRoot = dirname(__DIR__, 3);
$outputDir = $projectRoot . '/build/examples';
if (!is_dir($outputDir)) {
mkdir($outputDir, 0777, true);
}
$result = (new XObjectTemplateCompiler())->compile(new CompileRequest(
html: '<div style="font-size:12;color:#111111">Signed by {{ name }}</div>'
. '<div style="font-size:10;color:#555555">Role: {{ role }}</div>',
width: 240.0,
height: 84.0,
context: [
'name' => 'Alice',
'role' => 'Approver',
],
));
$outputFile = $outputDir . '/basic-template-result.json';
file_put_contents($outputFile, json_encode([
'content_stream_length' => strlen($result->contentStream),
'resources' => $result->resources,
'bbox' => $result->bbox,
'metadata' => $result->metadata,
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
return [
'example' => 'basic-template',
'generated_files' => [$outputFile],
'content_stream' => $result->contentStream,
'resources' => $result->resources,
'bbox' => $result->bbox,
];
preview-pdf.php — export a single-page PDF preview
<?php
// SPDX-FileCopyrightText: 2026 LibreSign
// SPDX-License-Identifier: AGPL-3.0-or-later
declare(strict_types=1);
use LibreSign\XObjectTemplate\Dto\CompileRequest;
use LibreSign\XObjectTemplate\Pdf\SinglePagePdfExporter;
use LibreSign\XObjectTemplate\XObjectTemplateCompiler;
require dirname(__DIR__, 3) . '/vendor/autoload.php';
$projectRoot = dirname(__DIR__, 3);
$outputDir = $projectRoot . '/build/examples';
if (!is_dir($outputDir)) {
mkdir($outputDir, 0777, true);
}
$result = (new XObjectTemplateCompiler())->compile(new CompileRequest(
html: '<div style="font-size:14;font-weight:700;color:#222222">Preview me</div>'
. '<div style="font-size:10;color:#666666;margin:6 0 0 0">Visible appearance test</div>',
width: 260.0,
height: 90.0,
));
$pdfBytes = (new SinglePagePdfExporter())->export($result);
$pdfFile = $outputDir . '/preview.pdf';
file_put_contents($pdfFile, $pdfBytes);
return [
'example' => 'preview-pdf',
'generated_files' => [$pdfFile],
'content_stream' => $result->contentStream,
'resources' => $result->resources,
'bbox' => $result->bbox,
'pdf_file' => $pdfFile,
];
images.php — embed PNG and JPEG assets from base64 fixtures
<?php
// SPDX-FileCopyrightText: 2026 LibreSign
// SPDX-License-Identifier: AGPL-3.0-or-later
declare(strict_types=1);
use LibreSign\XObjectTemplate\Dto\CompileRequest;
use LibreSign\XObjectTemplate\Pdf\SinglePagePdfExporter;
use LibreSign\XObjectTemplate\XObjectTemplateCompiler;
require dirname(__DIR__, 3) . '/vendor/autoload.php';
$projectRoot = dirname(__DIR__, 3);
$assetDir = $projectRoot . '/docs/source/examples/assets';
$outputDir = $projectRoot . '/build/examples';
$outputAssetDir = $outputDir . '/assets';
if (!is_dir($outputAssetDir)) {
mkdir($outputAssetDir, 0777, true);
}
$pngPath = $outputAssetDir . '/tiny.png';
$jpegPath = $outputAssetDir . '/tiny.jpg';
$pngBytes = base64_decode((string) file_get_contents($assetDir . '/tiny-png.base64'), true);
$jpegBytes = base64_decode((string) file_get_contents($assetDir . '/tiny-jpeg.base64'), true);
if (!is_string($pngBytes) || !is_string($jpegBytes)) {
throw new RuntimeException('Failed to decode example image assets.');
}
file_put_contents($pngPath, $pngBytes);
file_put_contents($jpegPath, $jpegBytes);
$html = '<div style="display:flex;flex-direction:row;align-items:center;gap:8;width:220;height:52">'
. '<img src="' . htmlspecialchars($pngPath, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . '" style="width:24px;height:24px" />'
. '<img src="' . htmlspecialchars($jpegPath, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . '" style="width:24px;height:24px" />'
. '<span style="font-size:10">PNG + JPEG</span>'
. '</div>';
$result = (new XObjectTemplateCompiler())->compile(new CompileRequest(
html: $html,
width: 260.0,
height: 90.0,
));
$pdfFile = $outputDir . '/images-preview.pdf';
$pdfBytes = (new SinglePagePdfExporter())->export($result);
file_put_contents($pdfFile, $pdfBytes);
$jsonFile = $outputDir . '/images-result.json';
file_put_contents($jsonFile, json_encode([
'bbox' => $result->bbox,
'resources' => $result->resources,
'metadata' => $result->metadata,
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
return [
'example' => 'images',
'generated_files' => [$pngPath, $jpegPath, $pdfFile, $jsonFile],
'content_stream' => $result->contentStream,
'resources' => $result->resources,
'bbox' => $result->bbox,
'pdf_file' => $pdfFile,
];
svg.php — render SVG content as an image source
<?php
// SPDX-FileCopyrightText: 2026 LibreSign
// SPDX-License-Identifier: AGPL-3.0-or-later
declare(strict_types=1);
use LibreSign\XObjectTemplate\Dto\CompileRequest;
use LibreSign\XObjectTemplate\Pdf\SinglePagePdfExporter;
use LibreSign\XObjectTemplate\XObjectTemplateCompiler;
require dirname(__DIR__, 3) . '/vendor/autoload.php';
$projectRoot = dirname(__DIR__, 3);
$outputDir = $projectRoot . '/build/examples';
$svgPath = $projectRoot . '/docs/source/examples/assets/sample.svg';
if (!is_dir($outputDir)) {
mkdir($outputDir, 0777, true);
}
$html = '<div style="display:flex;align-items:center;gap:8;width:280;height:80">'
. '<img src="' . htmlspecialchars($svgPath, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . '" style="width:96px;height:36px" />'
. '<span style="font-size:10;color:#222222">SVG sample</span>'
. '</div>';
$result = (new XObjectTemplateCompiler())->compile(new CompileRequest(
html: $html,
width: 280.0,
height: 100.0,
));
$pdfFile = $outputDir . '/svg-preview.pdf';
$pdfBytes = (new SinglePagePdfExporter())->export($result);
file_put_contents($pdfFile, $pdfBytes);
$jsonFile = $outputDir . '/svg-result.json';
file_put_contents($jsonFile, json_encode([
'bbox' => $result->bbox,
'resources' => $result->resources,
'metadata' => $result->metadata,
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
return [
'example' => 'svg',
'generated_files' => [$pdfFile, $jsonFile],
'content_stream' => $result->contentStream,
'resources' => $result->resources,
'bbox' => $result->bbox,
'pdf_file' => $pdfFile,
];
placement.php — demonstrate placement calculations
<?php
// SPDX-FileCopyrightText: 2026 LibreSign
// SPDX-License-Identifier: AGPL-3.0-or-later
declare(strict_types=1);
use LibreSign\XObjectTemplate\Dto\CompileRequest;
use LibreSign\XObjectTemplate\Integration\XObjectPlacementCalculator;
use LibreSign\XObjectTemplate\XObjectTemplateCompiler;
require dirname(__DIR__, 3) . '/vendor/autoload.php';
$projectRoot = dirname(__DIR__, 3);
$outputDir = $projectRoot . '/build/examples';
if (!is_dir($outputDir)) {
mkdir($outputDir, 0777, true);
}
$result = (new XObjectTemplateCompiler())->compile(new CompileRequest(
html: '<div style="font-size:10">Placement baseline</div>',
width: 240.0,
height: 84.0,
));
$calculator = new XObjectPlacementCalculator();
$fromWidth = $calculator->fromWidth($result, 175.0, 36.0, 72.0);
$fromHeight = $calculator->fromHeight($result, 61.25, 36.0, 72.0);
$fromScale = $calculator->fromScale($result, 0.729167, 36.0, 72.0);
$outputFile = $outputDir . '/placement-result.json';
file_put_contents($outputFile, json_encode([
'from_width_command' => $fromWidth->toPdfCommand('Fm0'),
'from_height_command' => $fromHeight->toPdfCommand('Fm0'),
'from_scale_command' => $fromScale->toPdfCommand('Fm0'),
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
return [
'example' => 'placement',
'generated_files' => [$outputFile],
'content_stream' => $result->contentStream,
'resources' => $result->resources,
'bbox' => $result->bbox,
];
interpolation.php — interpolate context variables in text
<?php
// SPDX-FileCopyrightText: 2026 LibreSign
// SPDX-License-Identifier: AGPL-3.0-or-later
declare(strict_types=1);
use LibreSign\XObjectTemplate\Dto\CompileRequest;
use LibreSign\XObjectTemplate\XObjectTemplateCompiler;
require dirname(__DIR__, 3) . '/vendor/autoload.php';
$projectRoot = dirname(__DIR__, 3);
$outputDir = $projectRoot . '/build/examples';
if (!is_dir($outputDir)) {
mkdir($outputDir, 0777, true);
}
$result = (new XObjectTemplateCompiler())->compile(new CompileRequest(
html: '<div style="font-size:10">Signed by {{ name }}</div>'
. '<div style="font-size:9">Role: {{ role }}</div>'
. '<div style="font-size:9">Missing: {{ missing }}</div>',
width: 260.0,
height: 90.0,
context: [
'name' => 'Alice <Admin>',
'role' => 'Approver',
],
));
$outputFile = $outputDir . '/interpolation-result.json';
file_put_contents($outputFile, json_encode([
'bbox' => $result->bbox,
'content_stream' => $result->contentStream,
'resources' => $result->resources,
'metadata' => $result->metadata,
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
return [
'example' => 'interpolation',
'generated_files' => [$outputFile],
'content_stream' => $result->contentStream,
'resources' => $result->resources,
'bbox' => $result->bbox,
];
How to run them
Output files
The integration scenario for examples writes generated artifacts to build/examples/
so the repository stays clean and the outputs remain disposable.
It also exports additional artifacts from reusable integration rendering scenarios to
build/examples/integration-scenarios/, so integration coverage doubles as practical examples.
Visible stamp integration scenarios are exported to build/examples/visible-stamp/
using the same shared scenario catalog and preview factory, including the GovBR-like
appearance as a first-class validated example.