FontoXML iframe CMS connector

The IFrame connector may be used to communicate with FontoXML using an IFrame. This may be necessary when it is technically infeasible to implement the endpoints in a CMS.

The FontoXML Iframe CMS Connector is an optional add-on for FontoXML. It can be used in implementations where it is technically impossible to implement the endpoints needed for the FontoXML Standard CMS Connector. Please use the preferred FontoXML Standard CMS Connector if possible.

The needed endpoints which are used by FontoXML to communicate with the CMS are normally called using HTTP API calls. The iframe connector instead uses Iframe communication for these calls.

The iframe connector is an add-on for FontoXML which caters to the need of implementation partners which are unable to implement the Standard CMS Connectors. For example, because there are technical limitations in the CMS which prevent the implementation of the needed HTTP API endpoints.

The iframe Connectors are wrappers around the same request and response models used by the Standard CMS Connectors as described in the CMS connectors API documentation and in the Integrate with a CMS. The wrappers are encapsulated in a message sent using postMessage. The message follows the same standard as other FontoXML iframe communication, like fontoxml-execute-operation, with the exception that event.data is not a JSON string but an actual object.

Also see the example in the use cases.

Usage

The iframe connector can be added to the FontoXML editor as an add-on.

When using the FontoXML development server, you can use the /iframe route for testing by adding the following code to the dev-cms/configureDevCms.js file in your editor repository.

'use strict';

const routes = [
	require('../platform/fontoxml-connectors-iframe/dev-cms/routes')
];

module.exports = (router, config) => {
	return {
		routes: routes.map(route => route(router, config))
	};
};

Embedding FontoXML

FontoXML editor must be hosted within its own Window. The reason for this requirement is isolation; in the current state of HTML5, CSS and JS it is not possible to introduce a well-defined isolation between the host application and the FontoXML editor. Consider global event handlers and the cascading part of CSS for example.

There are two ways to effectively isolate the FontoXML editor in its own Window:

  1. Load the FontoXML editor in an iframe.
  2. Embed the FontoXML editor in a new window via window.open.

    When opening the FontoXML editor in a new window, you should still embed the FontoXML editor in an iframe inside the newly opened window. The reason being, when you would open a FontoXML editor instance in a new window, and the user closes the CMS window, the editor can no longer make requests to it’s parent window and thus will generate errors.

When running Fonto in an iframe, please make sure that this frame has focus when Fonto loads. This will allow Fonto to correctly respond to input and (if documents are loaded) place the cursor and allow users to start editing immediately. To focus the iframe, obtain a reference to its DOM element and call the focus method. For example:

document.getElementById('fonto-iframe').focus();

Communicating with a FontoXML editor instance

The following section describes the API which allows the host application to communicate with a FontoXML editor instance.

The low-level API

The low-level API works by sending a request message from the FontoXML editor instance to the host application. These requests would otherwise have been sent by the Standard CMS Connectors using a HTTP request. The receiving host application must process the message, perform the actual CMS logic and send a response message back to the FontoXML editor instance.

Because of the way postMessage works, the order of request messages and response messages cannot be guaranteed. The messages contain a correlationId field which is used to identify which response belongs to which request.

HTML5 Web Messaging

The messages are passed back and forth between the host application and the FontoXML editor instance using HTML5 Web Messaging. See window.postMessage for additional details about this API.

Message data is passed along a normal JavaScript object using the the structured clone algorithm. The structured clone algorithm allows for JavaScript objects to be communicated, as well as File, Blob, RegExp, ImageData and other native JavaScript objects. Please refer to other sources for more information on these types.

Browser support

The FontoXML editor has certain client requirements. The supported browsers all support the postMessage API.

Security

The current implementation does not implement additional security features, because the FontoXML editor instance should only run in a controlled environment.

Message format and serialization

The message parameter of each postMessage, also called data, should be an object containing the relevant properties.

Request message

This describes the request object, after JSON deserialization, as sent by the FontoXML editor instance to the host application.

RequestMessage
type required string

The type of the message. Must be of value ‘fontoxml-connectors-iframe’.

Example value: "fontoxml-connectors-iframe".

correlationId required string

A unique identifier that is used to identify which response message belongs to which request message.

Example value: "3896C13C-C63D-4F57-8438-06D3EEB616A9".

scope required string

The scope object as passed along to the FontoXML editor instance by the host application. This contains, among others, the editSessionToken.

See Invocation of the Fonto Editor.

metadata required RequestMetadata

The wrapper object around the Standard CMS Connector request.

See Response metadata.

Response message

This describes the response object, before JSON deserialization, as send by the host application to the FontoXML editor instance.

ResponseMessage
type required string

The type of the message. Must be of value ‘fontoxml-connectors-iframe’.

Example value: "fontoxml-connectors-iframe"

correlationId required string

A unique identifier that is used to identify which response message belongs to which request message.This should match the correlationId as send in the request message.

Example value: "3896C13C-C63D-4F57-8438-06D3EEB616A9".

metadata required ResponseMetadata

The wrapper object around the Standard CMS Connector response.

See Request metadata.

Request metadata (a.k.a. Standard CMS request wrapper)

RequestMetadata
method required string

The HTTP method for the request.

Example value: "GET".

url required string

The url for the HTTP API endpoint as defined by the Standard CMS Connector.

Example value: "/document".

header required Object

A key value pair of the HTTP request headers. This might contain headers like accept, content-type or etag.

Example value
{
	"accept": "application/json"
}
query optional Object

A key value pair of the HTTP query parameters.

See CMS connectors API.

body optional mixed

The data, also known as the HTTP POST data.

See CMS connectors API.

Usually this is an object containing key/value pairs. For some implementations this can also include other types like Blob, FormData or a string.

multiparts optional array[string|File|Blob]

Optional. Some requests use multipart requests, for example file upload. This array contains all the parts. For example request data and binary file data.The filename property is optional, and is only set when the part is a file upload.The value property can be a string or a File or Blob object.

See CMS connectors API.


Example value
[
	{
		"name": "request",
		"value": { "json": "data" }
	},
	{
		"name": "file",
		"filename": "image.png",
		"value": <File>
	}
]

Response metadata (a.k.a. Standard CMS response wrapper)

ResponseMetadata
header required Object

A key value pair of the HTTP request headers. This might contain headers like accept, content-type or etag.

Example value
{
	"content-type": "application/json"
}
status required number

A HTTP response code as defined by the Standard CMS connector.

Example value: 200.

body optional Object

The data, also known as the HTTP response body.

See CMS connectors API.

Additional endpoints

There are also some unique endpoints for the iframe connector. These endpoints are used to retrieve URLs for asset download, asset preview and document preview.

GET /document/preview/url

Request query parameters

Request query parameters
context required Object

The context for the request.

See CMS connectors API.

documentId required string

The unique identifier of the document to get the preview for.

Example value: "74257961-EDE3-4180-AF17-0A435EE8FB7B".

Response body

Status: 200 (You can also return a 400, 403 or 404 status)

{
	"url": "<documentPreviewUrl>"
}

GET /asset/url

Request query parameters

Request query parameters
context required Object

The context for the request.

See CMS connectors API.

id required string

The unique identifier of the asset to download.

Example value: "007E87C5-C05F-495B-AC08-E880D5AB9FDA".

Response body

Status: 200 (You can also return a 400, 403 or 404 status)

{
	"url": "<assetDownloadUrl>"
}

GET /asset/preview/url

Request query parameters

Request query parameters
context required Object

The context for the request.

See CMS connectors API.

variant required string

The preferred preview variant to retrieve.

Example value: "web".

id required string

The unique identifier of the asset to download.

Example value: "007E87C5-C05F-495B-AC08-E880D5AB9FDA".

Response body

Status: 200 (You can also return a 400, 403 or 404 status)

{
		"url": "<assetPreviewUrl>"
}

Examples

GET /document

Request message

{
	"type": "fontoxml-connectors-iframe",
	"correlationId": "f9f908a8-f1aa-4e55-a96e-f1806595bea9",
	"scope": {
		"documentIds": [ "74257961-EDE3-4180-AF17-0A435EE8FB7B" ]
	},
	"metadata": {
		"method": "GET",
		"url": "/document",
		"header": {
			"cache-control": "no-cache",
			"pragma": "no-cache",
			"accept": "application/json"
		},
		"query": {
			"context": "{\"editSessionToken\":\"EF091CD9-DC7A-4F91-9964-21CAF0DC3DCE\"}",
			"documentId": "74257961-EDE3-4180-AF17-0A435EE8FB7B"
		}
	}
}

Response message

{
	"type": "fontoxml-connectors-iframe",
	"correlationId": "f9f908a8-f1aa-4e55-a96e-f1806595bea9",
	"metadata": {
		"header": {
			"content-type": "application/json; charset=utf-8"
		},
		"status": 200,
		"body": {
			"documentId": "74257961-EDE3-4180-AF17-0A435EE8FB7B",
			"revisionId": "206D7015-B824-4054-BC13-ABAE54D175DF",
			"content": "<xml />",
			"lock": {
				"isLockAcquired": true,
				"isLockAvailable": true
			},
			"metadata": {}
		}
	}
}

PUT /document

Request message

{
	"type": "fontoxml-connectors-iframe",
	"correlationId": "1e91f838-946f-4309-abca-1fbd21b5d827",
	"scope": {
		"documentIds": [ "74257961-EDE3-4180-AF17-0A435EE8FB7B" ]
	},
	"metadata": {
		"method": "PUT",
		"url": "/document",
		"header": {
			"accept": "application/json",
			"content-type": "application/json"
		},
		"data": {
			"context": {
				"editSessionToken": "EF091CD9-DC7A-4F91-9964-21CAF0DC3DCE"
			},
			"documentId": "74257961-EDE3-4180-AF17-0A435EE8FB7B",
			"revisionId": "206D7015-B824-4054-BC13-ABAE54D175DF",
			"content": "<xml />",
			"metadata": {},
			"autosave": true
		}
	}
}

Response message

{
	"type": "fontoxml-connectors-iframe",
	"correlationId": "1e91f838-946f-4309-abca-1fbd21b5d827",
	"metadata": {
		"header": {},
		"status": 200,
		"data": {
			"revisionId": "547C0CC5-3C3B-4C78-B7A2-B3C9BEF36A61"
		}
	}
}

POST /asset

Request message

{
	"type": "fontoxml-connectors-iframe",
	"correlationId": "3f381c42-a2c6-4fca-d657-c0f4032ca7b4",
	"scope": {
		"documentIds": [ "74257961-EDE3-4180-AF17-0A435EE8FB7B" ]
	},
	"metadata": {
		"method": "POST",
		"url": "/asset",
		"header": {
			"accept": "application/json"
		},
		"multiparts": [
			{
				"name": "request",
				"value": "{\"context\":{\"editSessionToken\":\"EF091CD9-DC7A-4F91-9964-21CAF0DC3DCE\",\"documentId\":\"74257961-EDE3-4180-AF17-0A435EE8FB7B\"},\"type\":\"image\",\"folderId\":null,\"metadata\":{}}"
			},
			{
				"name": "file",
				"filename": "image.png",
				"value": <File>
			}
		]
	}
}

Response message

{
	"type": "fontoxml-connectors-iframe",
	"correlationId": "3f381c42-a2c6-4fca-d657-c0f4032ca7b4",
	"metadata": {
		"header": {
			"etag": "W/\"6b-+qq6vLWSXbjAstzmhjPrqg\"",
			"content-length": "107",
			"content-type": "application/json; charset=utf-8"
		},
		"status": 201,
		"body": {
			"id": "image.jpg",
			"type": "image",
			"label": "Image",
			"metadata": {}
		}
	}
}
Was this page helpful?