Turn templates into finished designs with the Android Engine API. Load a template, populate its variables and image placeholders with your own data, and export the result to a PNG or PDF.
Template generation transforms a reusable template into a finished design by populating data and exporting the result. Load a template with engine.scene.load(), replace its variables and placeholders with the Variable and Block APIs, then export it with engine.block.export().
This guide covers loading templates, populating variables, updating placeholder content, exporting to images and PDFs, and running batch generation. To merge a template into an existing scene while keeping its canvas size, see Apply Templates. For a deeper look at replacing content, see Replace Content.
Loading Templates#
Load a template as the active scene before populating and exporting it. Pass a serialized string from your storage to engine.scene.load(scene=_), use engine.scene.load(sceneUri=_) for a remote or bundled .scene file, or call engine.scene.loadArchive(archiveUri=_) for an archive that includes its assets.
Set overrideEditorConfig = true to import the template’s registered variables and settings. The example builds and serializes an inline template for a self-contained sample; production templates normally come from your storage or a template authoring workflow.
engine.scene.load( scene = templateString, overrideEditorConfig = true, waitForResources = true,)Populating Variables#
Templates reference variables with {{variableName}} tokens in their text blocks. Setting a variable replaces every matching token throughout the scene.
Discover Available Variables#
Use engine.variable.findAll() to list the variables a template registers, then read a current value with engine.variable.get(). Variable names are case-sensitive.
val variableNames = engine.variable.findAll()val defaultRecipient = engine.variable.get(key = "recipientName")Set Variable Values#
Assign a value with engine.variable.set(). The matching text tokens update immediately.
engine.variable.set(key = "recipientName", value = "Avery")engine.variable.set(key = "message", value = "Wishing you a wonderful year ahead!")Updating Placeholder Content#
Templates can contain placeholder blocks for images and other content. Discover them with engine.block.findAllPlaceholders(), or find a known slot by its stable name with engine.block.findByName().
val placeholders = engine.block.findAllPlaceholders()val imagePlaceholder = engine.block.findByName(name = "Image").first()val namedPlaceholder = engine.block.getName(imagePlaceholder)Update Image Placeholders#
Read the placeholder’s fill with engine.block.getFill(), then update its image URI with engine.block.setUri(). The sample receives assetBaseUri from the host app so the URI can follow your bundled or self-hosted asset configuration.
val replacementImageUri = assetBaseUri.buildUpon() .appendPath("ly.img.image") .appendPath("images") .appendPath("sample_2.jpg") .build()val imageFill = engine.block.getFill(imagePlaceholder)engine.block.setUri( block = imageFill, property = "fill/image/imageFileURI", value = replacementImageUri,)engine.block.resetCrop(block = imagePlaceholder)Exporting to Images#
Find the populated page and export it to PNG with engine.block.export(). ExportOptions controls the target dimensions and format-specific options.
val page = engine.scene.getPages().first()engine.block.forceLoadResources(blocks = listOf(page))val pngData = engine.block.export( block = page, mimeType = MimeType.PNG, options = ExportOptions(targetWidth = 800F, targetHeight = 600F),).asReadOnlyBuffer()Exporting to PDF#
Export the scene block with MimeType.PDF to include every page in a multi-page document.
val scene = requireNotNull(engine.scene.get()) { "No scene loaded for export." }val pdfData = engine.block.export( block = scene, mimeType = MimeType.PDF,).asReadOnlyBuffer()Batch Generation Workflows#
Drive one template with multiple data records. Serialize the template once, then reload it with overrideEditorConfig = true for each record before setting variables and exporting. Reloading restores the template’s registered defaults so values do not leak between records.
val records = listOf( "Jordan" to "Congratulations on the new home!", "Riley" to "Thank you for everything.",)val batchExports = mutableListOf<ByteBuffer>()
for ((recipientName, message) in records) { engine.scene.load( scene = templateString, overrideEditorConfig = true, waitForResources = true, ) engine.variable.set(key = "recipientName", value = recipientName) engine.variable.set(key = "message", value = message)
val recordPage = engine.scene.getPages().first() engine.block.forceLoadResources(blocks = listOf(recordPage)) batchExports += engine.block.export( block = recordPage, mimeType = MimeType.PNG, ).asReadOnlyBuffer()}Troubleshooting#
Template Fails to Load#
Confirm that the input contains valid scene data and is compatible with your SDK version. For URI-based templates, verify that the URI is reachable and use loadArchive() instead of load() for archive files.
Variables Not Updating#
Ensure the key passed to engine.variable.set() exactly matches the {{token}} in the template. Use engine.variable.findAll() to inspect registered variable names.
Export Returns Empty Output#
Confirm that every referenced asset is reachable and that all blocks are attached to the page hierarchy. Call engine.block.forceLoadResources() before exporting content with remote images or fonts.
Image Placeholder Not Found#
Verify that the name passed to engine.block.findByName() matches the block name exactly. Use engine.block.findAllPlaceholders() to discover every placeholder in the scene.
API Reference#
| Method | Category | Purpose |
|---|---|---|
engine.scene.load(scene=_) |
Scene | Load a template from a serialized string |
engine.scene.load(sceneUri=_) |
Scene | Load a template from a remote or bundled URI |
engine.scene.loadArchive(archiveUri=_) |
Scene | Load a template archive with embedded assets |
engine.scene.saveToString(scene=_) |
Scene | Serialize a template for batch processing |
engine.scene.get() |
Scene | Get the active scene block |
engine.scene.getPages() |
Scene | Get the pages in the active scene |
engine.variable.findAll() |
Variable | List every registered variable |
engine.variable.set(key=_, value=_) |
Variable | Set and register a variable value |
engine.variable.get(key=_) |
Variable | Read a variable value |
engine.block.findByName(name=_) |
Block | Find blocks by name |
engine.block.findAllPlaceholders() |
Block | Discover all placeholder blocks |
engine.block.getName(block=_) |
Block | Read a block’s stable name |
engine.block.getFill(block=_) |
Block | Get a block’s fill |
engine.block.setUri(block=_, property=_, value=_) |
Block | Set an image fill URI |
engine.block.resetCrop(block=_) |
Block | Recalculate crop after replacing an image |
engine.block.export(block=_, mimeType=_, options=_) |
Block | Export a block to PNG, JPEG, or PDF |
Next Steps#
- Templates Overview — Understand how templates work in CE.SDK
- Apply Templates — Merge a template into an existing scene while preserving its dimensions
- Replace Content — Update variables and placeholders in depth
- Use Templates Programmatically — Build and personalize templates entirely in code