Renditionable
QName: f:renditionable
Marks that an instance or type is to have one or more renditions.
Renditions are other nodes in the branch whose content is automatically generated and kept in sync as the source node is created, updated and deleted (or has its relevant attachment modified).
Configuration
<thead>
<tr>
<th>Property</th>
<th>Type</th>
<th>Default</th>
<th nowrap>Read-Only</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>schedule</td>
<td>text</td>
<td></td>
<td></td>
<td>
Determines when renditions will be generated.
<br/>
Either <code>synchronous</code> or <code>asynchronous</code>.
</td>
</tr>
<tr>
<td>renditions</td>
<td>object</td>
<td></td>
<td></td>
<td>
Defines the renditions that you would like to have generated. Each rendition is keyed with a name
and provides a configuration that is passed to a rendition engine for execution.
</td>
</tr>
</tbody>
Renditionable Example (using a script
s)
Here is a node that has the f:renditionable
feature enabled. The general form looks something like this:
{
"title": "My Article",
"longHeadline": "Cubs win the World Series in game 6 by a score of 201 to 3 in Wrigley Field, Chicago!",
"mediumHeadline": "Cubs win World Series by score of 201 to 3!";
"shortHeadline": "Cubs win World Series!";
"_features": {
"f:renditionable": {
"renditions": {
"{renditionKey}": {
"engineId": "{id of the renditioning engine to use}",
"targetNodeId": "{targetNodeId}",
"targetAttachmentId": "{targetAttachmentId}",
"targetAttachmentMimeType": "{targetAttachmentMimeType}",
}
}
}
}
}
The exact properties that should be specified depend on the requirements of the renditioning engine. Here is a more concrete example that executes a script to create the new node:
{
"title": "My Article",
"longHeadline": "Cubs win the World Series in game 6 by a score of 201 to 3 in Wrigley Field, Chicago!",
"mediumHeadline": "Cubs win World Series by score of 201 to 3!";
"shortHeadline": "Cubs win World Series!";
"_features": {
"f:renditionable": {
"renditions": {
"mobile": {
"engineId": "script",
"scriptNodeId": "custom:script1"
}
}
}
}
}
The script engine will run the JavaScript contained as the default attachment on the script node. The script node is identified by custom:script1
. Note that this the QName for the script node but it may also be identified by it's node _doc
property.
For the script engine, a simple rendition
method must be provided that takes in a node and returns the JSON for the resulting object.
function rendition(node) {
return {
"title": node.data.title,
"headline": node.data.shortHeadline,
"format": "mobile"
};
}
As a result, a new node will be generated with the JSON:
{
"title": "My Article",
"headline": ""Cubs win World Series!",
"format": "mobile"
}
The new node is marked with the f:rendition
feature. It has an association of type a:has_rendition
that connects it from the source node to the rendition. This association has a property on it called renditionKey
with the value mobile
.
The source node will be marked with the f:renditioned
feature to indicate that a rendition was generated. That way, in the future, if you ever update the source node, all of the target renditions will likewise be regenerated.
For example, you might modify the source node's shortHeadline
to be "Cubs lose World Series!"
. Upon saving the source node, the target rendition (above) will update to:
{
"title": "My Article",
"headline": ""Cubs lose World Series!",
"format": "mobile"
}
Which would be a sad thing indeed. But here in Chicago, we're quite used to the Cubs losing. We'll get over it. And we'll be back next season!
Rendition Engines
The following rendition engines are available:
attachment
copy
nodelist
script
Attachment Rendition Engine (attachment
)
This rendition engine will copy and optionally transform an attachment from the document source to the target rendition.
Here is an example of an article that has a download
rendition configured for it. The rendition takes the article's data
attachment and copies it to a renditioned node as that node's default
attachment. The renditioned attachment is converted to application/pdf
. If the renditioned node doesn't yet exist, it will be created and it will have the Type QName of my:download
.
{
"title": "My Article",
"_type": "my:article",
"_features": {
"f:renditionable": {
"renditions": {
"download": {
"engineId": "attachment",
"sourceAttachmentId": "data",
"targetAttachmentId": "default",
"targetTypeQName": "my:download",
"targetAttachmentMimeType": "application/pdf"
}
}
}
}
}
As users make changes to the article, the rendition will be kept in sync.
The content graph will look like:
[My Article (my:article)] -> (a:has_rendition) -> [Rendition Node (my:download)]
Copy Rendition Engine (copy
)
This rendition engine will copy a source document to a target rendition.
Here is an example of an article that has a copy
rendition configured for it. The rendition takes the article's source JSON and creates a copy of the given target type.
{
"title": "My Article",
"_type": "my:article",
"_features": {
"f:renditionable": {
"renditions": {
"copy": {
"engineId": "copy"
}
}
}
}
}
As users make changes to the article, the rendition will be kept in sync.
The content graph will look like:
[My Article (my:article)] -> (a:has_rendition) -> [Rendition Node (my:article)]
NodeList Rendition Engine (nodelist
)
This rendition engine will execute a script to map a source document into a target document that is a list item in a node list.
Here is an example of a custom:book
content type that has f:renditionable
as a mandatory feature. This feature is configured with a books
rendition that will map the source document into a new list item content type (custom:booksListItem
). The resulting instance will then be added to a data list where key
is books
.
{
"_qname":"custom:book",
"_type":"d:type",
"type":"object",
"description":"Node List Test Book Type",
"properties":{},
"mandatoryFeatures": {
"f:renditionable": {
"renditions": {
"books": {
"engineId": "nodelist",
"scriptNodeId": "custom:script1",
"listKey": "books",
"listItemType": "custom:booksListItem"
}
}
}
}
}
The custom:booksListItem
content type might look like this:
{
"_qname":"custom:booksListItem",
"_type":"d:type",
"type":"object",
"description":"Books list item type",
"properties":{
"title": {
"type": "string"
},
"author": {
"type": "string"
}
}
}
The script (custom:script
) that we use to make article instances into book list items might look like this:
function rendition(node)
{
return {
"title": node.data.title,
"author": node.data.author
};
}
Thus, when users make changes to books, the renditioning engine will produce list item instances by executing the mapping function above against those books. Each book will sync to one row in the resulting list.
The graph ends up looking like this:
Book 1 (custom:book) -> (a:has_rendition) -> Rendition List Item 1 (custom:booksListItem) <- (a:has_item) <----\
Book 2 (custom:book) -> (a:has_rendition) -> Rendition List Item 2 (custom:booksListItem) <- (a:has_item) <--\ \
Book 3 (custom:book) -> (a:has_rendition) -> Rendition List Item 3 (custom:booksListItem) <- (a:has_item) <------ List (books)
Book 4 (custom:book) -> (a:has_rendition) -> Rendition List Item 4 (custom:booksListItem) <- (a:has_item) <--/ /
Book 5 (custom:book) -> (a:has_rendition) -> Rendition List Item 5 (custom:booksListItem) <- (a:has_item) <---/
Script Rendition Engine (script
)
This rendition engine will execute a custom server-side script to produce a target JSON that will constitute the renditioned node.
A good example is already shown above. In essence, a source article (shown here) can have a rendition defined on it that runs a script, like this:
{
"title": "My Article",
"longHeadline": "Cubs win the World Series in game 6 by a score of 201 to 3 in Wrigley Field, Chicago!",
"mediumHeadline": "Cubs win World Series by score of 201 to 3!";
"shortHeadline": "Cubs win World Series!";
"_features": {
"f:renditionable": {
"renditions": {
"mobile": {
"engineId": "script",
"scriptNodeId": "custom:script1"
}
}
}
}
}
And the script itself might look something like this:
function rendition(node) {
return {
"title": node.data.title + " Rendition",
"headline": node.data.shortHeadline + " (Who would have thought?)",
"format": "mobile"
};
}
The resulting renditioned node JSON will look like:
{
"title": "My Article Rendition",
"headline": "Cubs win World Series! (Who would have thought?)",
"format": "mobile"
}