Create Custom Template Placeholders
Scroll PDF Exporter provides a variety of placeholders that can be used in templates to include dynamic data while exporting, such as the current space name or the page creator's name.
As an app developers you might want to contribute information from your app in exports as well. While you can always do this with macros, in order to make this available in a reusable export template, a custom placeholder is required.
Therefore, Scroll PDF Exporter supports 3rd-party placeholders through a Velocity based API. The velocity-based approach ensures that your app has neither runtime nor buildtime dependencies to Scroll PDF Exporter code.
Required steps
To create a custom placeholder you need to:
- Create or extend an existing App
- Add a new
<velocity-context-item>
plugin module - Add two Java methods matching our API signatures to this module, one for returning the placeholder's values and one returning the placeholder specification format for making it appear in the template designer
After installing the app, the placeholder will appear in the template designer's Insert placeholder dialog:
Example of custom placeholder
To see an example of a custom placeholder, you can visit our Bitbucket page.
Register the placeholder
In order to be recognized as placeholder by Scroll Exporters the placeholder modules must fulfil these requirements:
The placeholder must be implemented as a Velocity Context Item module:
CODE<velocity-context-item key="exp-my-placeholder" name="Example Placeholder" context-key="exp-placeholder-example" class="com.k15t.examples.ExamplePlaceholder" global="true"/>
- The
context-key
attribute's value must be prefixed withexp-
. The value after the prefix must be unique, and it should be readable and indicative of the placeholder's function.
While not directly visible to the user in Scroll PDF Exporter, this value is used by other Scroll Exporter apps, for example by Scroll Word Exporter to identify the placeholder in custom templates. - The
global
attribute must be set totrue
They must implement (at least) the following Java methods:
JAVApublic class ExamplePlaceholder { public String render(Map<String, Supplier<String>> context) { ... } public String getPlaceholderSpec() { ... } }
- The
getPlaceholderSpec
method must return a valid placeholder spec.
Java API
String render(Map<String, Supplier<String>> context)
Description | This method is called whenever the placeholder is rendered during the export process. Each invocation of this method runs in its own transaction. There is no need for implementations to create their own transaction. |
---|---|
Parameters | The context object contains both general context information about the export, such as references to the space and page being exported, as well as the placeholder specific parameter as declared in the placeholder spec. Keys in this this map follow this pattern:
Values in this map are always |
Return Value | Must return HTML representing the output of the placeholder. The returned HTML should be self-contained and only reference external resources if they are either publicly available without authentication or if they are served by Confluence and can be accessed by the user performing the export. The implementation is responsible for properly escaping any user-supplied input before integrating it into the HTML output. |
String getPlaceholderSpec()
Description | This method is called whenever third-party placeholders are collected. The specification it returns contains requested parameters and information on how the placeholder will appear in user interfaces. |
---|---|
Parameters | - |
Return Value | Must return JSON following the structure documented below. |
Available parameters
Key | Description |
---|---|
export.contentId | The ID of the root page or blog post of the export. |
export.spaceKey | The key of the space that contains the root page or blog post. |
export.templateId | The ID of the template used in the export. |
export.templateName | The name of the template used in the export. |
export.locale | BCP 47 language tag representing the locale used for formatting dates and other data. It may be the exporting user's locale or a locale defined in the template. |
export.productKey | The key of the exporter add-on. |
export.productVersion | The version of the exporter add-on. |
placeholder.display | The display mode for which to evaluate the placeholder: "inline" or "block". This value may be defined in the placeholder spec or set to "user-defined", in which case the user can choose the display mode when inserting the placeholder into the template. |
Placeholder specification format
{
"version": "1", // Optional. Defaults to "1".
"metadata": {
"title": "My person placeholder title", // Used as display title for the placeholder
"description": "Returns some information on some person", // Optional. Displayed in the placeholder list and in placeholder dialog. Defaults to "".
"display": "inline" // Optional, either "inline", "block" or "user-defined", defaults to "inline"
},
"parameters": [
{
"key":"name", // Used in the context map as part of the keys
"title": "Full Name", // Displayed in the placeholder dialog
"description": "Enter the first and last name here", // Optional. Displayed in the placeholder dialog. Defaults to "".
"type": "string", // Displays as a single-line input field
"defaultValue": "" // Optional, defaults to null if not specified
},
{
"key":"age",
"title": "Age",
"description": "Enter the age in months here",
"type": "int", // Displays as a input field accepting numbers
"defaultValue": "273" // Optional, defaults to 0 if not specified
},
{
"key":"gender",
"title": "Gender",
"description": "Enter the gender here",
"type": "enum", // Displays as a dropdown
"defaultValue": "unspecified", // Optional, defaults to first allowed value, must match one of the keys in 'allowedValues'
"allowedValues": [ // Only available for enums. Must not be empty.
{
"key": "female", // Used in the context map as value for this parameter
"title": "Female" // Displayed in the dropdown
},
{
"key": "male",
"title": "Male"
},
{
"key": "unspecified",
"title": "No indication"
}
]
},
{
"key":"newsletter",
"title": "Send Newsletter",
"description": "Send hourly newsletter?",
"type": "boolean", // Displays as a checkbox
"defaultValue": "true" // Optional, defaults to false if not specified
}
]
}