Skip to content

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

Open on GitHub

<?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

Open on GitHub

<?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

Open on GitHub

<?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

Open on GitHub

<?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

Open on GitHub

<?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

Open on GitHub

<?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

composer run examples:test

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.